ホームページ  >  記事  >  Java  >  Java スレッドのインタビューの質問を要約して整理する

Java スレッドのインタビューの質問を要約して整理する

WBOY
WBOY転載
2022-06-29 15:15:541610ブラウズ

この記事では、java に関する関連知識を提供します。主にスレッド インタビューの質問に関連する問題を整理します。これには、sychronied で変更された通常のメソッドと静的メソッドの違い、CAS ロックフリー プログラミングの原理、違いが含まれます。 volatile と synchronize の間など、一緒に見ていきましょう。皆さんのお役に立てれば幸いです。

Java スレッドのインタビューの質問を要約して整理する

推奨学習: 「java ビデオ チュートリアル

1. 通常のメソッドと静的メソッドの同期変更方法の違いは?可視性とは何ですか?

オブジェクト ロックはオブジェクト インスタンス メソッドまたはオブジェクト インスタンスに使用され、クラス ロックはクラスの静的メソッドまたはクラスのクラス オブジェクトに使用されます。クラスには多数のオブジェクト インスタンスが存在する可能性があることがわかっていますが、各クラスにはクラス オブジェクトが 1 つしかないため、異なるオブジェクト インスタンスのオブジェクト ロックは互いに干渉しませんが、各クラスに存在するクラス ロックは 1 つだけです。
注意しなければならないのは、クラス ロックは概念的なものであり、実際には存在せず、実際には各クラスの対応するクラス オブジェクトをロックすることです。クラス ロックとオブジェクト ロックも相互に干渉しません。
可視性とは、複数のスレッドが同じ変数にアクセスするときに、1 つのスレッドが変数の値を変更すると、他のスレッドが変更された値をすぐに確認できることを意味します。
スレッドによる変数の操作はすべて作業メモリ内で実行する必要があり、メイン メモリ内の変数を直接読み書きすることはできないため、共有変数 V については、最初に独自の作業メモリに配置され、次にメイン メモリに同期されます。メモリ。 。ただし、メインメモリへのフラッシュが間に合わず、ある程度の時間差が生じます。明らかに、この時点では、変数 V に対するスレッド A の操作はスレッド B からは認識されなくなります。
共有オブジェクトの可視性の問題を解決するには、volatile キーワードまたはロックを使用できます。

2. ロックのカテゴリは何ですか?

Java スレッドのインタビューの質問を要約して整理する

3. CAS ロックフリー プログラミングの原理。

現在のプロセッサは基本的に CAS() 命令をサポートしていますが、メーカーごとに実装されているアルゴリズムが異なり、各 CAS 演算プロセスにはメモリアドレス V、期待値 A、新しい値 B の 3 つの演算子が含まれています。このアドレスに格納されている値が期待値 A と等しい場合、そのアドレスの値は新しい値 B に割り当てられます。それ以外の場合、操作は実行されません。
CAS の基本的な考え方は、このアドレスの値が期待値と等しい場合は新しい値を与え、それ以外の場合は何もせずに元の値を返すというものです。ループ CAS は、cas 操作を成功するまでループで実行し続けることです。 CAS に関する 3 つの主要な問題についてもお話します。

4. ReentrantLock の実装原理。

スレッドは、すでに所有しているロックと同期している任意のコード ブロックに繰り返し入ることができます。Synchronized ロックと ReentrantLock は両方とも再入可能なロックです。実装面では、スレッドがロックを取得するたびに、ロックを取得しているスレッドが自分自身であるかどうかを判断し、単純にカウンタを累積します。ロックが解放されるたびに、計算機がゼロに戻るまでカウンタはデクリメントされます。スレッドが完全に解放されました。ロックします。最下層は JUC の AQS を使用して実装されます。

5. AQS の原則。

これは、ロックやその他の同期コンポーネントを構築するために使用される基本的なフレームワークです。たとえば、ReentrantLock、ReentrantReadWriteLock、CountDownLatch は AQS に基づいて実装されます。 int メンバー変数を使用して同期ステータスを表し、組み込み FIFO キューを使用してリソース取得スレッドのキューイング作業を完了します。これは、CLH キュー ロックの変形実装です。排他的と共有の 2 つの同期方法を実現できます。
AQS を使用する主な方法は継承です。サブクラスは AQS を継承し、その抽象メソッドを実装して同期ステータスを管理します。シンクロナイザーの設計はテンプレート メソッド パターンに基づいているため、独自の同期ツール クラスを実装する場合は、 tryAcquire、tryReleaseShared などのいくつかのオーバーライド可能なメソッド。
この設計の目的は、同期コンポーネント (ロックなど) がユーザー指向であることです。これは、ユーザーが同期コンポーネントと対話するためのインターフェースを定義し (たとえば、2 つのスレッドが並行してアクセスできるようにします)、実装を非表示にします。詳細; シンクロナイザはユーザー指向です。ロックの実装者です。ロックの実装を簡素化し、同期状態管理、スレッドのキューイング、待機およびウェイクアップなどの基礎となる操作をシールドします。これにより、ユーザーと実装者が注力する必要がある領域が効果的に分離されます。
内部的には、AQS は共有リソースの状態を維持し、組み込み FIFO を使用してリソース取得スレッドのキューイング作業を完了します。キューは 1 つずつ Node ノードで構成され、各 Node ノードは、それぞれ自身の先行ノードと後続ノードを指す前参照と次参照を保持し、両端の二重リンク リストを形成します。

6. Synchronized の原理と ReentrantLock との違い。

同期 (この) 原則: 2 つの命令:monitorenter、monitorexit が含まれます; 同期メソッドについて話しましょう。同期メソッドの逆コンパイル結果から判断すると、メソッドの同期は、monitorenter およびmonitorexit 命令を通じては達成されません。通常のメソッドと比較して、定数プールに追加の ACC_SYNCHRONIZED 識別子があります。
JVM は、この識別子に基づいてメソッド同期を実装します。メソッドが呼び出されるとき、呼び出し命令は、メソッドの ACC_SYNCHRONIZED アクセス フラグが設定されているかどうかを確認します。設定されている場合、実行スレッドは最初にモニターを取得します。取得が成功すると、メソッド本体を実行でき、メソッド実行後にモニターを解放できます。メソッドの実行中、他のスレッドは同じモニター オブジェクトを再度取得できません。

7. Synchronized が行った最適化の内容

スピン ロック、適応スピン ロック、ロック除去、ロック粗密化、バイアス ロック、軽量ロック、エスケープ解析などのテクノロジーの導入、およびその他の削減のためのテクノロジーロック操作のコスト。

  • エスケープ分析: オブジェクトがメソッドまたはスレッドの外にエスケープしないことが証明された場合、この変数を最適化できます:
  • 同期削除 : 同期 削除。オブジェクトがスレッドからエスケープしない場合、この変数の同期手段を削除できます。
  • ロックの削除と粗いロックの削除: 仮想マシンのランタイム コンパイラが、実行時に同期を必要とする一部のコードで共有データの競合が発生する可能性が低いことを検出した場合、これらのロックを削除します。 。
  • ロック粗大化: 隣接するコード ブロックを同じロックと結合します。無意味なロックの取得と解放を排除することで、プログラムの実行パフォーマンスを向上させることができます。

8. 同期された静的ロックと非静的ロックの違いと範囲。

オブジェクト ロックは、オブジェクト インスタンス メソッドまたはオブジェクト インスタンスに使用され、クラス ロックは、クラスの静的メソッドまたはクラスのクラス オブジェクトに使用されます。クラスには多数のオブジェクト インスタンスが存在する可能性があることがわかっていますが、各クラスにはクラス オブジェクトが 1 つしかないため、異なるオブジェクト インスタンスのオブジェクト ロックは互いに干渉しませんが、各クラスに存在するクラス ロックは 1 つだけです。
注意しなければならないのは、クラス ロックは概念的なものであり、実際には存在せず、実際には各クラスの対応するクラス オブジェクトをロックすることです。クラス ロックとオブジェクト ロックも相互に干渉しません。

9. volatile はスレッドの安全性を保証できますか? DCL では何をするのでしょうか?

DCL の役割が次であるという保証はありません。 volatile は変更された変数の可視性と順序を保証し、シングルトン モードではオブジェクト作成時の実行順序が

であることを保証します。
  1. メモリ空間の割り当て
  2. オブジェクト インスタンスのインスタンス化
  3. インスタンス参照が割り当てられたメモリ空間を指すようにします。この時点で、インスタンスにはメモリ アドレスがあり、null ではなくなります。 . . したがって、インスタンスが null または完全に初期化されたオブジェクトのいずれかであることが保証されます。

10. 揮発性と同期の違いは何ですか?

Volatile は最も軽量な同期メカニズムです。 Volatile は、さまざまなスレッドがこの変数を操作するときの可視性を保証します。つまり、1 つのスレッドが変数の値を変更すると、新しい値は他のスレッドからすぐに可視になります。ただし、volatile は操作のアトミック性を保証できないため、マルチスレッドでの複合書き込み操作ではスレッドの安全性の問題が発生します。
キーワード synchronized は、メソッドまたは同期ブロックの形式を変更するために使用できます。これは主に、複数のスレッドがメソッドまたは同期ブロック内で同時に 1 つのスレッドのみを持つことができることを保証します。これにより、スレッドが変数に安全にアクセスできるようになります。可視性と排他性。組み込みロック機構とも呼ばれます。

11. デーモン スレッドとは何ですか?スレッドを終了するにはどうすればよいですか?

デーモン スレッドは、主にプログラムのバックグラウンド スケジューリングとサポート作業に使用されるため、サポート スレッドです。これは、Java 仮想マシンに非デーモン スレッドが存在しない場合、Java 仮想マシンは終了することを意味します。 Thread.setDaemon(true) を呼び出すことで、スレッドをデーモン スレッドとして設定できます。通常は使用しませんが、たとえば、ガベージ コレクション スレッドはデーモン スレッドです。
スレッド中止: 実行の実行が完了するか、ハンドルされない例外がスローされ、スレッドが早期に終了します。操作の一時停止、再開、停止を行うスレッド Thread に対応する API は、suspend()、resume()、stop() です。ただし、これらの API は古いため、使用はお勧めできません。プログラムが不確実な状態で動作することになるからです。
安全な一時停止とは、他のスレッドが、interrupt() メソッドを呼び出して、特定のスレッド A に割り込むことです。割り込まれたスレッドは、スレッド メソッド isInterrupted() によって割り込まれたかどうか、または静的メソッド Thread.interrupted を呼び出すことができるかどうかを判断します。 () は現在のスレッドが割り込まれているかどうかを判断するために使用されますが、Thread.interrupted() は割り込みフラグ ビットも false に書き換えます。

12. スリープ、待機、および降伏の違い 待機スレッドはどのようにウェイクアップするのでしょうか?

yield() メソッド: 現在のスレッドに CPU 所有権を放棄させますが、放棄する時間を設定することはできません。ロックリソースは解放されません。 yield() を実行するすべてのスレッドは、オペレーティング システムによって再度選択され、準備完了状態に入った直後に実行される場合があります。
yield() と sleep() が呼び出された後、現在のスレッドによって保持されているロックは解放されません。
wait() メソッドを呼び出した後、現在のスレッドが保持しているロックが解放され、現在のスレッドが起動された後、再度ロックを競合します。wait メソッドの背後にあるコードは、待機メソッドの呼び出し後にのみ実行されます。ロックが競合します。
Wait は通常、スレッド間の対話に使用され、sleep は通常、実行の一時停止に使用され、yield() メソッドにより現在のスレッドに CPU 所有権を放棄させます。
待機スレッドは、notify/notifyAll() を使用してウェイクアップします。

13. スリープは中断可能ですか?

スリープ中にスレッドが中断されると、割り込み例外がスローされます。

14. スレッドのライフサイクル。

Java のスレッドのステータスは 6 つのタイプに分類されます。

  1. Initial (NEW): 新しいスレッド オブジェクトが作成されますが、start() メソッドはまだ呼び出されていません。 。
  2. 実行 (RUNNABLE): Java スレッドでは、準備完了と実行中の 2 つの状態を一般に「実行中」と呼びます。スレッド オブジェクトが作成された後、他のスレッド (メイン スレッドなど) がオブジェクトの start() メソッドを呼び出します。この状態のスレッドは実行可能なスレッド プールに配置され、CPU の使用権を取得するためにスレッド スケジューリングによって選択されるのを待っており、この時点では準備完了状態になります。準備完了状態のスレッドは、CPU タイムスライスを取得した後、実行状態 (running) に変化します。
  3. ブロック済み (BLOCKED): スレッドがロック内でブロックされていることを示します。
  4. 待機中 (WAITING): この状態に入ったスレッドは、他のスレッドが特定のアクション (通知または中断) を実行するのを待つ必要があります。
  5. タイムアウト待機 (TIMED_WAITING): この状態は WAITING とは異なり、指定された時間が経過すると自動的に戻ることができます。
  6. TERMINATED (TERMINATED): スレッドが実行を完了したことを示します。

Java スレッドのインタビューの質問を要約して整理する

15. ThreadLocal とは何ですか?

ThreadLocal は Java の特別な変数です。 ThreadLocal は各スレッドに変数のコピーを提供するため、各スレッドが特定の時点で同じオブジェクトにアクセスすることがなくなり、複数のスレッドによるデータの共有が分離されます。
内部実装に関しては、各スレッドには内部に ThreadLocalMap があり、各スレッドが所有する変数のコピーを保存するために使用されます。

16. スレッド プールの基本原則。

開発プロセス中、スレッド プールを合理的に使用すると 3 つのメリットが得られます。
まず: リソース消費を削減します。
2 番目: 応答速度の向上。
3 番目: スレッドの管理性を向上させます。

  1. 現在実行中のスレッドの数が corePoolSize 未満の場合は、タスクを実行するための新しいスレッドを作成します (この手順を実行するには、グローバル ロックを取得する必要があることに注意してください)。
  2. 実行中のスレッドが corePoolSize 以上の場合、タスクを BlockingQueue に追加します。
  3. タスクを BlockingQueue に追加できない (キューがいっぱいである) 場合は、タスクを処理する新しいスレッドを作成します。
  4. 新しいスレッドを作成すると、現在実行中のスレッドが minimumPoolSize を超える場合、タスクは拒否され、RejectedExecutionHandler.rejectedExecution() メソッドが呼び出されます。

17. 3 つのスレッド T1、T2、および T3 があります。これらが順番に実行されることを確認するにはどうすればよいですか?

join メソッドを使用して実装できます。

推奨学習: 「Java ビデオ チュートリアル

以上がJava スレッドのインタビューの質問を要約して整理するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcsdn.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。