2020年秋の採用に関する最新のインタビューの質問:同時プログラミングの高頻度のインタビューの質問:再入可能ロック+スレッドプール+メモリモデルなど(回答を含む)

Javaプログラマーにとって、並行プログラミングをマスターできることは、彼の卓越性を判断するための重要な基準の1つです。並行プログラミングはJava言語で最も不明瞭な知識ポイントであるため、オペレーティングシステム、メモリ、CPU、プログラミング言語などの基本的な機能が含まれ、プログラマーの内部スキルをテストします。
では、並行プログラミングをどのように学習しますか?Java SDKには多数の並行ツールキットがあります。各ツールの長所と短所、および使用シナリオを覚えておく必要がありますか?もちろん覚えていません。並行プログラミングを学びたい場合は、1つから学ぶ必要があります中国の知識と技術から「飛び出し」、ハイレベルな視点で問題を見つめ、徐々に独自の知識体系を確立。

ReentrantLockおよびその他の明示的なロック関連の問題

質問1:再入可能ロックの実装原理の違いは、同期化と比較して何ですか?

実際、ロックの実現原理は基本的に1つの目標を達成することです。つまり、すべてのスレッドに特定のマークを表示させることです。Synchronizedは、オブジェクトヘッダーにマークを設定することでこの目標を達成します。これは、JVMネイティブロック実装メソッドです。リエントラントロックおよびLockインターフェースに基づくすべての実装クラスは、volitile-modified int変数を使用してすべて実装されます。各スレッドがintの可視性とアトミック変更を確実に行えるようにするために、その本質はいわゆるAQSフレームワークに基づいています。

質問2:それでは、AQSフレームワークについてお話しください。

AQS(Abstract Queued Synchronizer class)は、ロックとシンクロナイザー、さまざまなロックパッケージのロック(一般にリエントラントロック、ReadWriteロックが使用されます)、およびセマフォ、カウントダウンラッチ、さらには初期のものなどのフレームワークです。今後のタスクなどはすべて、構築するAQSに基づいています。

1. AQSは、揮発性のint状態変数を内部的に定義します。これは、同期状態を表します。スレッドがロックメソッドを呼び出すとき、state = 0の場合、共有リソースのロックを保持しているスレッドがなく、ロックを取得でき、state = 1、つまり状態の場合= 1は、スレッドが現在共有変数を使用しており、他のスレッドが同期キューに参加して待機する必要があることを意味します。

2. AQSは、Nodeの内部クラスによって形成された二重にリンクされたリスト構造を持つ同期キューを介してロックを取得するスレッドのキューイング作業を完了します。スレッドがロックの取得に失敗すると、それはキューの最後に追加されます。

  • Nodeクラスは、同期コードにアクセスするスレッドのカプセル化です。これには、スレッド自体と待機ステータスと呼ばれるそのステータスが含まれます(ブロックされているかどうか、ウェイクアップを待機しているかどうか、キャンセルされているかどうかなどを示す5つの異なる値があります)。ノードノードは、前のノードと次のノードを関連付けて、ロックを解除した後、スレッドが次の待機中のスレッドをすばやく起動できるようにします。これはFIFOプロセスです。
  • Nodeクラスには2つの定数、SHAREDとEXCLUSIVEがあり、それぞれ共有モードと排他モードを表します。いわゆる共有モードは、複数のスレッドが同時に動作することを可能にするロックであり(セマフォセマフォはAQSの共有モードに基づいています)、排他モードは、同じ期間に1つのスレッドのみが共有リソースを操作できるため、冗長な要求スレッドをキューに入れる必要があります待機します(Reentran Lockなど)。

3. AQS

内部クラスのConditionオブジェクトを使用して待機キュー(複数ある場合があります)を構築します。Conditionがwait()メソッドを呼び出すと、スレッドは待機キューに参加し、Conditionがsignal()メソッドを呼び出すと、スレッドは待機キューからモバイル同期に移動しますキュー内の競合をロックします。

4. AQS

と条件はそれぞれ異なるキューを保持します。ロックと条件を使用すると、実際には2つのキュー間を移動します。

質問3:同期ロックと再入可能ロックの類似点と相違点をできるだけ比較してください。

Reentrant Lockは、相互に排他的な同期ロックであるLockの実装クラスです。

機能の観点から見ると、再入可能ロックはSynchronizedの同期操作よりも洗練されており(通常のオブジェクトのように使用できるため)、Synchronizedにはない次のような高度な機能も実装しています。

  • 待機は中断される可能性があります:ロックを保持しているスレッドが長時間ロックを解放しない場合、待機スレッドは待機を中止することを選択できます。これは、実行時間が非常に長い同期ブロックの処理に役立ちます。
  • タイムアウトでロックを取得しようとします。指定された時間範囲内でロックを取得し、時間が経過しても取得できない場合は戻ります。
  • ロックを獲得するためにキューで待機しているスレッドがあるかどうかを判別できます。
  • 割り込み要求に応答できる:Synchronizedとは異なり、ロックを取得したスレッドが割り込みを受けると、割り込みに応答でき、割り込み例外がスローされ、ロックが解放されます。
  • フェアロックを実現できます。

ロックの解放の観点から見ると、SynchronizedはJVMレベルで実装されています。同期されたロックは、一部の監視ツールで監視できるだけでなく、コードの実行が異常な場合、JVMは自動的にロックを解放しますが、Lockの使用は機能しません。ロックが確実に解放されるようにするには、finally {}にun Lock()を配置する必要があります。

パフォーマンスの観点から見ると、Synchronizedの初期の実装は比較的非効率的であり、リエントラントロックと比較して、ほとんどのシナリオのパフォーマンスはかなり異なります。しかし、それは、競争が激しくないJava 6で大幅に改善されました。

SynchronizedのパフォーマンスはReetrant Lockのパフォーマンスよりも優れています。競争が激しい場合、Synchronizedのパフォーマンスは何十倍も低下しますが、Reetrant Lockのパフォーマンスは通常のままです。

質問4:再入可能ロックはどのようにして再入可能にしますか?

再入可能ロックは、シンクロナイザの同期を内部的にカスタマイズします(同期はAQSとAOSの両方を実装し、AOSはミューテックスロックを保持する方法を提供します)実際、ロックがロックされている場合、CASアルゴリズムを使用してスレッドオブジェクトを配置します。二重リンクリストでは、ロックが取得されるたびに、現在維持されているスレッドIDが現在要求されているスレッドIDと同じであり、同じIDを再入力できるかどうかを確認します。

質問5:Reetrant Lockに加えて、JUCでどの並行性ツールを利用しましたか?

質問6:読み取り書き込みロックとスタンプロックについて話してください。

質問7:Javaスレッドを互いに同期させる方法は?どのシンクロナイザを知っていますか?別途ご紹介ください。

質問8:循環バリアとカウントダウンラッチは非常によく似ています。比較してください。

Javaスレッドプール関連の問題

質問1:スレッドプールはJavaでどのように実装されますか?

Javaでは、スレッドプールのいわゆる「スレッド」は、実際には静的内部クラスWorkerとして抽象化され、AQSに基づいて実装され、スレッドプールのHash Set <Worker>ワーカーメンバー変数に格納されます。

実行する必要があるタスクは、メンバー変数の作業キュー(Blocking Queue <Runnable>作業キュー)に格納されます。このようにして、スレッドプール全体の実現の基本的な考え方は、実行する必要があるタスクを継続的に作業キューから取り出し、それらをワーカーに配置して処理することです。

質問2:スレッドプールを作成するには、コア構築パラメーターがいくつ必要ですか。

Javaでのスレッドプールの作成は、実際には非常に柔軟です。さまざまなパラメーターを構成することで、さまざまな動作のスレッドプールを作成できます。これらのパラメーターには、次のものがあります。コアプールサイズ:スレッドプール内のコアスレッドの数。

  • 最大プールサイズ:スレッドプールで許可されるスレッドの最大数。
  • キープアライブ時間:コアスレッドの数を超えたときのアイドルスレッドのサバイバル時間。
  • 作業キュー:タスクが実行される前にタスクを保存し、executeメソッドによって送信されたRunnableタスクを保存するキュー。

質問3:スレッドプール内のスレッドはどのように作成されますか?スレッドプールの開始時に最初に作成されましたか?

明らかにそうではありません。スレッドプールがデフォルトで初期化された後、ワーカーは開始されず、要求がある場合にのみ開始されます。execute()メソッドを呼び出してタスクを追加するたびに、スレッドプールは次の判断を行います。

実行中のスレッドの数がコアプールサイズより少ない場合は、すぐにスレッドを作成してこのタスクを実行します。

実行中のスレッドの数がコアプールサイズ以上の場合、タスクをキューに入れます。

この時点でキューがいっぱいで、実行中のスレッドの数が最大プールサイズより少ない場合は、非コアスレッドを作成してタスクをすぐに実行します。

キューがいっぱいで、実行中のスレッドの数が最大プールサイズ以上である場合、スレッドプールは例外Reject Execution Exceptionをスローします。スレッドは、そのタスクを完了すると、実行のためにキューから次のタスクを削除します。スレッドが一定期間何もしない場合(キープアライブ時間)、スレッドプールは切断されます。

現在実行中のスレッドの数がコアプールサイズより大きい場合、このスレッドは停止します。したがって、スレッドプールのすべてのタスクが完了すると、最終的にコアプールサイズのサイズに縮小されます。

質問4:異なるパラメーターを構成することで異なるスレッドプールを作成できるとのことですが、Javaではデフォルトでどのスレッドプールが実装されますか?それらの類似点と相違点を比較してください。

質問5:Javaスレッドプールでスレッドを送信する方法

…………………………

Javaメモリモデル関連の問題

質問1:Javaのメモリモデルとは何ですか?また、Javaのスレッドはお互いの変数をどのように認識しますか?

Javaのメモリモデルは、プログラム内の各変数のアクセスルールを定義します。つまり、仮想マシンに変数を格納したり、メモリから変数を削除したりするなど、低レベルの詳細を定義します。

ここでの変数には、配列オブジェクトを構成するインスタンスフィールド、静的フィールド、および要素が含まれますが、ローカル変数とメソッドパラメーターは含まれません。これらはスレッドプライベートであり、共有されないため、競合の問題はありません。

Javaのスレッドは、お互いの変数をどのように見ているか?メインメモリとワーキングメモリの概念は、Javaで定義されています。

すべての変数はメインメモリに格納され、各スレッドには独自のワーキングメモリがあり、スレッドが使用する変数のメインメモリのコピーが格納されます。スレッドによる変数のすべての操作(読み取り、割り当て)は作業メモリで実行する必要があり、メインメモリ内の変数を直接読み書きすることはできません。異なるスレッドは、互いのワーキングメモリの変数に直接アクセスできません。スレッド間の変数値の転送は、メインメモリを通過する必要があります。

質問2:volatileの特性と、すべてのスレッドが変数の可視性を保証できる理由を教えてください。

質問3:volatileはスレッド間の変数の可視性を保証できるので、volatile変数に基づく操作が同時に安全であることを意味しますか?

質問4:volatileとSynchronizedの類似点と相違点を比較してください。

質問5:スレッドローカルが並行性の安全性をどのように解決するかについて教えてください。

質問6:スレッドローカルは慎重に使用する必要があると多くの人が言いますが、スレッドローカルを使用するときに注意する必要があることについて、理解について教えてください。

……………………

同期関連の問題

質問1:Synchronizedを使用したことがありますか?その原理は何ですか?

質問2:オブジェクトのロックの取得について説明しましたが、この「ロック」とは正確には何ですか?オブジェクトのロックを判別する方法は?

質問3:再入可能性とは何ですか?Synchronizedが再入可能ロックであるのはなぜですか?再入可能

質問4:JVMはJavaのネイティブロックに対してどのような最適化を行いますか?

質問5:Synchronizedが不当なロックになるのはなぜですか?

質問6:ロックの除去とロックの粗大化とは何ですか?

質問7:Synchronizedが悲観的ロックになるのはなぜですか?楽観的ロックの原則は何ですか?CASとは何ですか?その特性は何ですか?

質問8:楽観的ロックは必ずしも適切ですか?

その他の問題

JAVA並行ナレッジベース

JAVAスレッドの実装/作成方法

4つのスレッドプール

スレッドのライフサイクル(状態)

スレッドを終了する4つの方法

睡眠と待機の違い

開始と実行の違い

JAVAバックグラウンドスレッド

JAVAロック

基本的なスレッドメソッド

スレッドコンテキストスイッチ

同期とデッドロック

スレッドプールの原理

JAVAブロッキングキューの原則

CyclicBarrier、CountDownLatch、Semaphoreの使用

volatileキーワードの役割(可変表示、並べ替え禁止)

2つのスレッド間でデータを共有する方法

ThreadLocal関数(スレッドローカルストレージ)

同期とリエントラントロックの違い

ConcurrentHashMapの並行性

Javaで使用されるスレッドスケジューリング

プロセススケジューリングアルゴリズム

CASとは何ですか(比較および交換-楽観的ロックメカニズム-ロックスピン)

AQS(Abstract Queue Synchronizer)とは

すべての同時プログラミングインタビューの質問がドキュメントにまとめられました。スペースが長いため、すべてをアップロードする方法はありません。完全な圧縮ドキュメントが必要なパートナーは、「VXアシスタントを追加して無料で入手できます」

                                                            

情報表示

 

同時プログラミングの高頻度インタビューの質問:再入可能ロック+スレッドプール+メモリモデルなど(回答を含む)

 

同時プログラミングの高頻度インタビューの質問:再入可能ロック+スレッドプール+メモリモデルなど(回答を含む)

 

知識脳マップ:

同時プログラミングの高頻度インタビューの質問:再入可能ロック+スレッドプール+メモリモデルなど(回答を含む)

 

文句を言いたくはありませんが、知識ポイントは多く、複雑です。

同時プログラミングの高頻度インタビューの質問:再入可能ロック+スレッドプール+メモリモデルなど(回答を含む)

おすすめ

転載: blog.csdn.net/a159357445566/article/details/108708515