121、スレッドとは何ですか?
スレッドは、オペレーティング システムが操作のスケジューリングを実行できる最小単位であり、プロセスに含まれ、プロセス内の実際の操作単位です。プログラマはこれをマルチプロセッサ プログラミングに使用でき、マルチスレッドを使用して計算負荷の高いタスクを高速化できます。たとえば、1 つのスレッドがタスクを完了するのに 100 ミリ秒かかる場合、10 個のスレッドを使用してタスクを完了するのにかかる時間はわずか 10 ミリ秒です。
(より関連した面接の質問に関する推奨事項: java 面接の質問と回答 )
122、スレッドとプロセスの違いは何ですか?
スレッドはプロセスのサブセットです。プロセスには多数のスレッドを含めることができ、各スレッドは異なるタスクを並行して実行します。異なるプロセスは異なるメモリ空間を使用し、すべてのスレッドは同じメモリ空間を共有します。各スレッドには、ローカル データを保存するための個別のスタック メモリがあります。
123、Java でスレッドを実装するにはどうすればよいですか?
2 つの方法: java.lang.Thread クラスのインスタンスはスレッドですが、実行するには java.lang.Runnable インターフェイスを呼び出す必要があります。スレッド クラス自体は呼び出される Runnable インターフェイスであるため、次のことができます。 java.lang .Thread クラスを継承するか、Runnable インターフェースを直接呼び出して run() メソッドをオーバーライドしてスレッドを実装します。
124、Java キーワード volatile と synchronized の機能と違いは何ですか?
1. Volatile
変更する変数はコピーを保持せず、メイン メモリに直接アクセスします。
Java メモリ モデルにはメイン メモリがあり、各スレッドにも独自のメモリ (レジスタなど) があります。パフォーマンスを向上させるために、スレッドはアクセスする変数のコピーを自身のメモリに保持します。このように、あるスレッドのメモリ内の同じ変数の値が、ある時点で別のスレッドのメモリ内の値またはメイン メモリ内の値と一致しない可能性があります。変数を volatile として宣言すると、変数はいつでも他のスレッドによって変更できるため、スレッド メモリにキャッシュできなくなります。
2. synchronized
メソッドまたはコード ブロックの変更に使用すると、最大 1 つのスレッドがコードを同時に実行することが保証されます。
1. 2 つの同時スレッドが同じオブジェクト内の同期された (この) 同期コード ブロックにアクセスする場合、一度に 1 つのスレッドのみを実行できます。別のスレッドは、このコード ブロックを実行する前に、現在のスレッドがこのコード ブロックの実行を完了するまで待つ必要があります。
2. ただし、スレッドがオブジェクトの同期された (この) 同期コード ブロックにアクセスするとき、別のスレッドは引き続きオブジェクト内の非同期 (この) 同期コード ブロックにアクセスできます。
3. 特に、スレッドが Object 内の同期された (この) 同期コード ブロックにアクセスすると、他のスレッドは Object 内の他のすべての同期された (この) 同期コード ブロックへのアクセスによってブロックされます。
4. スレッドがオブジェクトの同期された (この) 同期コード ブロックにアクセスすると、このオブジェクトのオブジェクト ロックを取得します。その結果、オブジェクト オブジェクトのすべての同期されたコード部分への他のスレッドのアクセスが一時的にブロックされます。
5. 上記のルールは、他のオブジェクト ロックにも適用できます。
125、さまざまなスレッドのライフ サイクルとは何ですか?
Java プログラムで新しいスレッドを作成すると、そのステータスは New になります。スレッドの start() メソッドを呼び出すと、ステータスが Runnable に変更されます。スレッド スケジューラは、実行可能スレッド プール内のスレッドに CPU 時間を割り当て、ステータスを実行中に変更します。他のスレッド状態には、待機中、ブロック済み、デッドなどがあります。
126 さん、スレッドの優先順位についてはどう理解していますか?
各スレッドには優先順位があります。一般に、実行時には優先順位の高いスレッドが優先されますが、これはオペレーティング システムに関連するスレッド スケジューリングの実装によって異なります (OS に依存します)。スレッドの優先順位を定義できますが、これは、優先順位の高いスレッドが優先順位の低いスレッドよりも前に実行されることを保証するものではありません。スレッドの優先順位は int 変数 (1 ~ 10) で、1 は最低の優先順位を表し、10 は最高の優先順位を表します。
127、デッドロックとは何ですか?デッドロックを分析して回避するにはどうすればよいですか?
デッドロックとは、3 つ以上のスレッドが永久にブロックされる状況を指します。この状況には、少なくとも 2 つ以上のスレッドと 3 つ以上のリソースが必要です。
デッドロックを分析するには、Java アプリケーションのスレッド ダンプを表示する必要があります。どのスレッドが BLOCKED ステータスにあり、どのスレッドが待機しているリソースを確認する必要があります。各リソースには一意の ID があり、この ID を使用して、どのスレッドがそのオブジェクト ロックをすでに所有しているかを調べることができます。
ネストされたロックを回避し、必要な場合にのみロックを使用し、無期限の待機を回避することが、デッドロックを回避する一般的な方法です。
128、スレッドセーフとは何ですか? Vector はスレッドセーフなクラスですか?
コードが配置されているプロセスで複数のスレッドが同時に実行されている場合、これらのスレッドがこのコードを同時に実行する可能性があります。各実行の結果がシングルスレッド実行の結果と同じであり、他の変数の値が予想どおり同じである場合、それはスレッドセーフです。スレッドセーフなカウンター クラスは、同じインスタンス オブジェクトが複数のスレッドで使用される場合でも計算エラーを引き起こしません。明らかに、コレクション クラスをスレッド セーフと非スレッド セーフの 2 つのグループに分けることができます。 Vector は同期メソッドを使用してスレッド セーフを実現しますが、それに似た ArrayList はスレッド セーフではありません。
(推奨される関連ビデオ チュートリアル: java コース )
129、Java でスレッドを停止するにはどうすればよいですか?
Java は豊富な API を提供しますが、スレッドを停止するための API は提供しません。 JDK 1.0 には当初、stop()、suspend()、resume() などのいくつかの制御メソッドがありましたが、潜在的なデッドロックの脅威のため、後続の JDK バージョンでは非推奨になりました。その後、Java API の設計者は、互換性のあるスレッドを提供しませんでした。スレッドを停止する安全な方法。 run() または call() メソッドが実行されると、スレッドは自動的に終了します。スレッドを手動で終了したい場合は、揮発性のブール変数を使用して run() メソッドのループを終了するか、タスクをキャンセルしてスレッドを中断します。
130, ThreadLocal とは何ですか?
ThreadLocal は、スレッドのローカル変数を作成するために使用されます。オブジェクトのすべてのスレッドがそのグローバル変数を共有することがわかっているため、これらの変数はスレッドセーフではありません. 同期技術を使用できます。ただし、同期を使用したくない場合は、ThreadLocal 変数を選択できます。
各スレッドには独自のスレッド変数があり、get()\set() メソッドを使用してデフォルト値を取得したり、スレッド内で値を変更したりできます。 ThreadLocal インスタンスは通常、関連するスレッド状態をプライベート静的プロパティにする必要があります。
131、Sleep()、suspend()、wait() の違いは何ですか?
Thread.sleep() は、指定された時間に現在のスレッドを「実行不可」状態にします。スレッドは常にオブジェクトのモニターを保持します。たとえば、スレッドが現在同期されたブロックまたはメソッド内にある場合、他のスレッドはそのブロックまたはメソッドに入ることができません。別のスレッドがinterrupt() メソッドを呼び出すと、「スリープ」スレッドが起動されます。
注: sleep() は静的メソッドです。これは、現在のスレッドに対してのみ有効であることを意味します。よくある間違いは、t.sleep() を呼び出すことです (t は現在のスレッドとは異なるスレッドです)。 t.sleep() が実行されても、t スレッドではなく、現在のスレッドがスリープ状態になります。 t.suspend() は時代遅れのメソッドです。suspend() を使用すると、スレッドが停滞状態になります。スレッドは常にオブジェクトの監視を保持します。Suspend() はデッドロックの問題を引き起こしやすいです。
Object.wait() は、現在のスレッドを「実行不可能」状態にします。 sleep() との違いは、wait がスレッドではなくオブジェクトのメソッドであることです。 object.wait() を呼び出す場合、スレッドはまずこのオブジェクトのオブジェクト ロックを取得する必要があります。現在のスレッドはロック オブジェクトの同期を維持し、現在のスレッドを待機キューに追加する必要があります。その後、別のスレッドが同じオブジェクト ロックを同期することができます。 object.notify() を呼び出し、元の待機中のスレッドを起動し、ロックを解放します。基本的に wait()/notify() は sleep()/interrupt() に似ていますが、前者はオブジェクト ロックを取得する必要がある点が異なります。
132、スレッド スターベーションとは何ですか?ライブロックとは何ですか?
すべてのスレッドがブロックされている場合、または必要なリソースが無効であるために処理できない場合、リソースを使用可能にする非ブロック スレッドは存在しません。 Java API でのスレッドのライブロックは、次の状況で発生する可能性があります。
1. プログラム内ですべてのスレッドが Object.wait(0) を実行すると、パラメーター 0 の wait メソッドが使用されます。プログラムは、スレッドが対応するオブジェクトに対して Object.notify() または Object.notifyAll() を呼び出すまでライブ ロックを続けます。
2. すべてのスレッドが無限ループに入った場合。
133、Java Timer クラスとは何ですか?特定の時間間隔でタスクを作成するにはどうすればよいですか?
java.util.Timer は、将来の特定の時刻にスレッドを実行するようにスケジュールするために使用できるツール クラスです。 Timer クラスを使用して、1 回限りのタスクまたは定期的なタスクをスケジュールできます。
java.util.TimerTask は、Runnable インターフェイスを実装する抽象クラスです。独自のスケジュールされたタスクを作成し、Timer を使用してその実行をスケジュールするには、このクラスを継承する必要があります。
134. Java における同期コレクションと同時コレクションの違いは何ですか?
同期コレクションと同時コレクションはどちらも、マルチスレッドと同時実行に適したスレッドセーフなコレクションを提供しますが、同時コレクションの方がよりスケーラブルです。
プログラマーは同期されたコレクションのみを使用でき、マルチスレッドが並行している場合に競合が発生し、システムのスケーラビリティが妨げられます。
Java5 では、ConcurrentHashMap のような同時コレクションが導入されています。これにより、スレッドの安全性が提供されるだけでなく、ロックの分離や内部パーティショニングなどの最新のテクノロジによってスケーラビリティが向上します。
135、同期メソッドと同期ブロック、どちらがより良い選択ですか?
同期ブロックはオブジェクト全体をロックしないため、より良い選択です (もちろん、オブジェクト全体をロックさせることもできます)。同期メソッドは、クラス内に無関係な同期ブロックが複数ある場合でもオブジェクト全体をロックします。これにより、通常、メソッドの実行が停止し、オブジェクトのロックを取得するまで待機する必要があります。
136、スレッド プールとは何ですか?なぜそれを使うのでしょうか?
はスレッドを作成すると長くなり、プロセス内で作成できるスレッドの数には制限があります。
このような問題を回避するために、プログラム起動時に処理に応答するスレッドを複数用意し、これをスレッドプールと呼び、その中のスレッドをワーカースレッドと呼びます。
JDK1.5 以降、Java API はさまざまなスレッド プールを作成できるように Executor フレームワークを提供します。たとえば、単一のスレッド プールは一度に 1 つのタスクを処理します。固定数のスレッド プールまたはキャッシュ スレッド プール (有効期間の短いタスクが多いプログラムに適した拡張可能なスレッド プール)。
137、Java の invokeAndWait と invokeLater の違いは何ですか?
これら 2 つのメソッドは、イベント ディスパッチ スレッドではなく現在のスレッドから GUI コンポーネントを更新するために、Swing API によって Java 開発者に提供されます。 InvokeAndWait() は、進行状況バーなどの GUI コンポーネントを同期的に更新します。進行状況が更新されたら、それに応じて進行状況バーも変更する必要があります。進行状況が複数のスレッドによって追跡される場合は、invokeAndWait() メソッドを呼び出して、イベント ディスパッチ スレッドにコンポーネントを更新するように要求します。 invokeLater() メソッドは、更新コンポーネントを非同期的に呼び出します。
138, マルチスレッドにおけるビジー ループとは何ですか?
ビジー ループとは、従来のメソッド wait() や sleep( とは異なり、プログラマがループを使用してスレッドを待機させることです) ) または yield() これらはすべて CPU 制御を放棄しますが、ビジー ループは CPU を放棄せず、空のループを実行するだけです。これの目的は、CPU キャッシュを保持することです。
マルチコア システムでは、待機中のスレッドが起動時に別のコアで実行されている可能性があり、これによりキャッシュが再構築されます。キャッシュの再構築を回避し、再構築の待ち時間を短縮するために使用できます。
関連する推奨事項: Java 入門チュートリアル
以上がJavaマルチスレッドの面接の質問の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。