JAVAインタビューの質問の最新コレクション(4)

マルチスレッド

35.並列処理と同時実行の違いは何ですか?

  • 並列とは、2つ以上のイベントが同時に発生することを意味します。並行性とは、2つ以上のイベントが同じ時間間隔で発生することを意味します。

  • 並行性は、異なるエンティティでの複数のイベントであり、並行性は、同じエンティティでの複数のイベントです。

  • 並列処理は、複数のプロセッサでの複数のタスクの同時処理であり、同時実行性は、1つのプロセッサでの複数のタスクの「同時」処理です。Hadoop分散クラスターなど。

36.スレッドとプロセスの違いは?

つまり、プロセスはプログラム操作とリソース割り当ての基本単位であり、プログラムには少なくとも1つのプロセスがあり、プロセスには少なくとも1つのスレッドがあります。

スレッドは、プロセスのエンティティであり、CPUのスケジューリングとディスパッチの基本単位であり、プログラムよりも小さく、独立して実行できる基本単位です。同じプロセス内の複数のスレッドを同時に実行できます。

独立性:プロセスには独自の独立したアドレス空間がありますが、スレッドにはありません。スレッドはプロセスに依存して存在する必要があります。

リソース共有:リソースはプロセス間で共有できませんが、スレッドはアドレス空間とそれらが配置されているプロセスの他のリソースを共有します。

オーバーヘッドの観点から。プロセス切り替えのオーバーヘッドは比較的大きいです。糸は比較的小さいです。

37.デーモンスレッドとは何ですか?

デーモンスレッド(つまりデーモンスレッド)はサービススレッドであり、正確には他のスレッドにサービスを提供します。

38.スレッドを作成する方法は何ですか?

①。Threadクラスを継承してスレッドクラスを作成します

Threadクラスのサブクラスを定義し、このクラスのrunメソッドをオーバーライドします。runメソッドのメソッド本体は、スレッドが完了するタスクを表します。したがって、run()メソッドは実行本体と呼ばれます。

Threadサブクラスのインスタンスを作成します。つまり、スレッドオブジェクトを作成します。

スレッドオブジェクトのstart()メソッドを呼び出して、スレッドを開始します。

②。Runnableインターフェースを介してスレッドクラスを作成します

実行可能インターフェースの実装クラスを定義し、インターフェースのrun()メソッドを書き直します。run()メソッドのメソッド本体は、スレッドのスレッド実行本体でもあります。

Runnable実装クラスのインスタンスを作成し、このインスタンスをThreadターゲットとして使用してThreadオブジェクトを作成します。Threadオブジェクトは実際のスレッドオブジェクトです。

スレッドオブジェクトのstart()メソッドを呼び出して、スレッドを開始します。

③.CallableとFutureを介してスレッドを作成する

Callableインターフェースの実装クラスを作成し、call()メソッドを実装します。call()メソッドはスレッド実行本体として機能し、戻り値を持ちます。

Callable実装クラスのインスタンスを作成し、FutureTaskクラスを使用してCallableオブジェクトをラップします。FutureTaskオブジェクトは、Callableオブジェクトのcall()メソッドの戻り値をカプセル化します。

FutureTaskオブジェクトをThreadオブジェクトのターゲットとして使用して、新しいスレッドを作成して開始します。

FutureTaskオブジェクトのget()メソッドを呼び出して、子スレッドの実行が終了した後に戻り値を取得します。

39.実行可能と呼び出し可能の違いについて教えてください。

Runnableインターフェイスのrun()メソッドの戻り値はvoidです。これは、run()メソッドのコードを純粋に実行するだけです。

Callableインターフェイスのcall()メソッドには戻り値があり、ジェネリック型です。FutureおよびFutureTaskとともに使用して、非同期実行の結果を取得できます。

40.スレッドのステータスは何ですか?

スレッドには通常、作成済み、準備完了、実行中、ブロック済み、および停止の5つの状態があります。

  • ステータスを作成します。スレッドオブジェクトが生成されるとき、オブジェクトのstartメソッドは呼び出されません。これは作成されるスレッドです。

  • 準備完了状態。スレッドオブジェクトのstartメソッドを呼び出した後、スレッドは準備完了状態になりますが、この時点では、スレッドスケジューラはスレッドを現在のスレッドとして設定しておらず、この時点で準備完了状態になっています。スレッドが実行され、待機またはスリープから復帰すると、スレッドも準備完了状態になります。

  • 動作状態。スレッドスケジューラは、スレッドを現在のスレッドとして準備完了状態に設定します。この時点で、スレッドは実行状態になり、run関数でコードの実行を開始します。

  • ブロックされた状態。スレッドが実行されているとき、スレッドは一時停止されます。通常、続行する前に、特定の時間(たとえば、特定のリソースの準備ができている)が発生するのを待ちます。スリープ、サスペンド、待機、およびその他の方法により、スレッドがブロックされる可能性があります。

  • 死の状態。スレッドのrunメソッドが終了するか、stopメソッドが呼び出されると、スレッドは停止します。停止したスレッドの場合、startメソッドを使用してスレッドを準備することはできなくなります

41. sleep()とwait()の違いは何ですか?

sleep():このメソッドはスレッドクラス(Thread)の静的メソッドであり、呼び出し元のスレッドがスリープ状態になり、他のスレッドに実行の機会を与えることができます。スリープ時間が終了すると、スレッドは準備完了状態になります。 CPUの実行時間について他のスレッドと競合します。sleep()は静的メソッドであるため、オブジェクトのマシンロックを変更することはできません。同期ブロックでsleep()メソッドを呼び出すと、スレッドはスリープ状態になりますが、オブジェクトのマシンロックは解除されず、他のスレッドはまだこのオブジェクトにアクセスできません。

wait():wait()はObjectクラスのメソッドです。スレッドがwaitメソッドを実行すると、オブジェクトに関連する待機プールに入り、同時にオブジェクトのマシンロックを解放して、他のスレッドが待機中のスレッドをウェイクアップするために、notify、notifyAllメソッドにアクセスできます。

42. notify()とnotifyAll()の違いは何ですか?

  • スレッドがオブジェクトのwait()メソッドを呼び出す場合、スレッドはオブジェクトの待機プールにあり、待機プール内のスレッドはオブジェクトのロックをめぐって競合しません。

  • スレッドがオブジェクトのnotifyAll()メソッド(すべての待機スレッドをウェイクアップする)またはnotify()メソッド(ランダムな待機スレッドのみがウェイクアップされる)を呼び出すと、ウェイクアップされたスレッドはオブジェクトのロックプールに入り、スレッドは競合しますオブジェクトロック用。つまり、notifyを呼び出した後、待機プールからロックプールに入るスレッドは1つだけであり、notifyAllは、オブジェクトの待機プール内のすべてのスレッドをロックプールに移動し、ロックの競合を待機します。

  • 優先度の高いスレッドは、オブジェクトロックを競合する可能性が高くなります。スレッドがオブジェクトロックを競合しない場合、スレッドはロックプールに残ります。スレッドがwait()メソッドを再度呼び出した場合にのみ、スレッドはロックプールに残ります。待機プールに戻ります。オブジェクトロックを競合するスレッドは、同期されたコードブロックが実行されるまで実行を継続し、オブジェクトロックを解放します。その後、ロックプール内のスレッドはオブジェクトロックを競合し続けます。

43.スレッドrun()とstart()の違いは何ですか?

各スレッドは、特定のThreadオブジェクトに対応するメソッドrun()を介して操作を完了します。メソッドrun()は、スレッド本体と呼ばれます。Threadクラスのstart()メソッドを呼び出してスレッドを開始します。

start()メソッドはスレッドを開始し、マルチスレッド操作を真に実現します。このとき、runメソッドの本体コードの実行が完了するのを待つ必要はありません。次のコードを直接実行し続けることができます。このとき、スレッドは準備完了状態であり、実行されていません。次に、このThreadクラスを介してメソッドrun()が呼び出され、実行状態が完了します。メソッドrun()は、実行されるスレッドのコンテンツを含むスレッド本体と呼ばれ、Runメソッドが終了し、スレッドが終了します。 。次に、CPUは他のスレッドをスケジュールします。

run()メソッドはこのスレッドにあり、マルチスレッドではなく、スレッド内の単なる関数です。run()を直接呼び出す場合、実際には通常の関数を呼び出すのと同じです。run()メソッドは、run()メソッドが完了するのを待ってから次のコードを実行する必要があるため、実行パスは1つだけです。はスレッドではありません。したがって、マルチスレッド実行では、run()メソッドの代わりにstart()メソッドを使用する必要があります。

44.スレッドプールを作成するいくつかの方法は何ですか?

①.newFixedThreadPool(int nThreads)
は、固定長のスレッドプールを作成し、タスクが送信されるたびに、スレッドプールの最大数に達するまでスレッドを作成します。この時点で、スレッドサイズは変更されなくなります。スレッドで予期しないエラーが発生する最後に、スレッドプールに新しいスレッドが追加されます。

②.newCachedThreadPool()
は、キャッシュ可能なスレッドプールを作成します。スレッドプールのサイズが処理要求を超えると、アイドル状態のスレッドが自動的にリサイクルされます。要求が増加すると、新しいスレッドを自動的に追加できます。のサイズに制限はありません。スレッドプール。。

③.newSingleThreadExecutor()
これはシングルスレッドのエグゼキュータであり、タスクを実行するための単一のワーカースレッドを作成します。このスレッドが異常終了した場合、新しいスレッドが作成されて置き換えられます。その特徴は、キューはシリアルに実行されることが保証されています。

④.newScheduledThreadPool(int corePoolSize)
は、固定長のスレッドプールを作成し、タイマーと同様に、遅延または時間指定された方法でタスクを実行します。

45.スレッドプールのステータスは何ですか?
スレッドプールには、実行中、シャットダウン、停止、整理、および終了の5つの状態があります。
ここに画像の説明を挿入
46.スレッドプールのsubmit()メソッドとexecute()メソッドの違いは何ですか?

  • 受信したパラメータが同じではありません

  • 送信には戻り値がありますが、実行にはありません

  • 例外処理を容易にするために送信する

47. Javaプログラムで複数のスレッドが安全に動作するようにするにはどうすればよいですか?

スレッドセーフは、次の3つの側面に反映されます。

  • Atomicity:相互に排他的なアクセスを提供します。同時にデータを操作できるのは1つのスレッドのみです(アトミック、同期)。

  • 可視性:スレッドによるメインメモリの変更は、他のスレッドによって時間内に確認できます(同期、揮発性)。

  • 順序性:スレッドは、他のスレッドの命令の実行順序を監視します。命令の順序が変更されるため、監視結果は一般に無秩序になります(原則の前に発生します)。つまり、このスレッドで観察すると、すべての操作が順番になります。別のスレッドで観察すると、すべての操作が順番どおりになりません。

48.マルチスレッドロックのアップグレードの原則は何ですか?

Javaには、ローからハイの4種類のロック状態があります。ステートレスロック、バイアスロック、ライトウェイトロック、ヘビーウェイトロックの状態です。これらの状態は、競合によって徐々にアップグレードされます。ロックはアップグレードできますが、ダウングレードすることはできません。
ここに画像の説明を挿入
49.デッドロックとは何ですか?

デッドロックとは、リソースの競合や実行中の通信により、2つ以上のプロセスがブロックされる現象であり、外力がないと前進できません。このとき、システムはデッドロック状態にある、またはシステムにデッドロックがあると言われ、常に相互に待機しているこれらのプロセスをデッドロックプロセスと呼びます。これはオペレーティングシステムレベルでのエラーです。プロセスデッドロックの略です。1965年に銀行家のアルゴリズムを研究していたときにダイクストラによって最初に提案されました。これは、コンピュータのオペレーティングシステムおよび全体でさえ最も難しい問題の1つです。並行プログラミングの分野。

50.デッドロックを防ぐ方法は?

デッドロックに必要な4つの条件:

  1. 相互に排他的な条件:プロセスは、他のプロセスが割り当てられたリソースにアクセスすることを許可しません。他のプロセスがリソースにアクセスする場合、リソースを占有するプロセスがリソースの解放に使用されるまで待機できます。

  2. 要求と保留の条件:プロセスが特定のリソースを取得した後、他のリソースに要求を送信しますが、そのリソースは他のプロセスによって占有されている可能性があります。この要求はブロックされますが、取得したリソースを保持し続けます。

  3. 不可侵の状態:プロセスが獲得したリソースを指します。使用する前に奪うことはできません。使用した後にのみ、自分で解放することができます。

  4. ループ待機状態:プロセスでデッドロックが発生した後、複数のプロセス間でヘッドツーテールの循環待機リソース関係が形成されることを指します。

これらの4つの条件は、デッドロックの必要条件です。システムがデッドロックされている限り、これらの条件を確立する必要があり、上記の条件のいずれかが満たされない限り、デッドロックは発生しません。

デッドロックの原因、特にデッドロックに必要な4つの条件を理解することで、デッドロックを可能な限り回避、防止、および解除できます。

したがって、システム設計、プロセススケジューリングなどの観点から、これら4つの必要な条件が確立されないようにする方法、およびプロセスがシステムリソースを永続的に占有しないようにするための適切なリソース割り当てアルゴリズムを決定する方法に注意してください。

また、待機状態でプロセスがリソースを占有しないようにする必要があります。したがって、リソースの割り当てには合理的な計画を立てる必要があります。

51. ThreadLocalとは何ですか?使用シナリオは何ですか?

スレッドローカル変数は、スレッドの内部に限定され、スレッド自体に属し、複数のスレッド間で共有されない変数です。Javaは、スレッドの安全性を実現する方法であるスレッドローカル変数をサポートするためのThreadLocalクラスを提供します。ただし、管理環境(Webサーバーなど)でスレッドローカル変数を使用する場合は注意が必要です。この場合、ワーカースレッドのライフサイクルは、アプリケーション変数のライフサイクルよりも長くなります。作業の完了後にスレッドローカル変数が解放されないと、Javaアプリケーションでメモリリークが発生するリスクがあります。

52.同期の基本的な実装原則について教えてください。

同期により、メソッドまたはコードブロックの実行時に、同時に1つのメソッドのみがクリティカルセクションに入ることができます。また、共有変数のメモリの可視性も確保できます。

Javaのすべてのオブジェクトは、同期を実現するための同期の基礎となるロックとして使用できます。

  • 通常の同期方法で、ロックは現在のインスタンスオブジェクトです

  • 静的同期メソッド。ロックは現在のクラスのクラスオブジェクトです。

  • 同期メソッドブロック、ロックは角かっこ内のオブジェクトです

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

  • Volatileは基本的に、レジスタ(作業メモリ)内の現在の変数の値が不確実であり、メインメモリから読み取る必要があることをjvmに通知します。
    同期は現在の変数をロックすることであり、現在のスレッドのみが変数にアクセスできます。他のスレッドブロックされます。

  • Volatileは変数レベルでのみ使用でき、synchronizedは変数、メソッド、およびクラスレベルで使用できます。

  • Volatileは、変数の変更の可視性のみを実現でき、原子性を保証することはできません。同期されている間は、変数の変更の可視性と原子性を保証できます。

  • 揮発性はスレッドブロッキングを引き起こしません;同期はスレッドブロッキングを引き起こす可能性があります。

  • volatileでマークされた変数は、コンパイラーによって最適化されません。synchronizedでマークされた変数は、コンパイラーによって最適化できます。

54.同期とロックの違いは何ですか?

  • まず、synchronizedはjavaの組み込みキーワードです。jvmレベルでは、Lockはjavaクラスです。

  • Synchronizedは、ロックの状態を取得するかどうかを判別できません。Lockは、ロックを取得するかどうかを判別できます。

  • Synchronizedは自動的にロックを解放し(スレッドは同期コードの実行後にロックを解放します。bは
    スレッドの実行中に例外が発生した場合にロックを解放します)、最後に手動でロックを解放する必要があります(unlock()メソッドはロックを解放します)、そうでない場合、スレッドをロック解除するのは簡単です。

  • 同期キーワードを持つ2つのスレッド1と2。現在のスレッド1がロックを取得すると、スレッド2は待機します。スレッド1がブロックされている場合、スレッド2は永久に待機し、ロックロックは必ずしも永久に待機するわけではありません。ロックを取得できない場合、スレッドは永久に待機せずに終了できます。

  • 同期ロックは、再入可能、中断不能、および不公平である可能性がありますが、ロックロックは、再入可能、判断、および公平である可能性があります(どちらも許容されます)。

  • ロックロックは、同期されたコードの数が多い同期の問題に適しており、同期されたロックは、コードの数が少ない同期の問題に適しています。

55.同期とReentrantLockの違いは何ですか?

Synchronizedはif、else、for、whileと同じキーワードであり、ReentrantLockはクラスであり、これが2つの本質的な違いです。ReentrantLockはクラスであるため、同期よりも柔軟な機能を提供します。継承、メソッド、さまざまなクラス変数を使用できます。ReentrantLockは、いくつかの点で同期よりも拡張性があります。

  • ReentrantLockは、デッドロックを回避するために、ロックを取得するための待機時間を設定できます。

  • ReentrantLockは、さまざまなロックに関する情報を取得できます

  • ReentrantLockは複数の通知を柔軟に実装できます

さらに、2つのロックメカニズムは実際には異なります。ReentrantLockの最下層がUnsafe parkメソッドを呼び出してロックし、同期された操作はオブジェクトヘッダーのマークワードである必要があります。

56.アトミックの原理について教えてください。

Atomicパッケージのクラスの基本的な機能は、マルチスレッド環境で、複数のスレッドが1つの変数(基本型と参照型を含む)で同時に動作する場合、つまり、複数のスレッドが同時に持っている場合に排他的であるということです。変数の値更新時には、1つのスレッドのみが成功でき、失敗したスレッドはスピンロックのように試行を続け、実行が成功するまで待機できます。

Atomicシリーズのクラスのコアメソッドは、安全でないクラスのいくつかのローカルメソッドを呼び出します。知っておく必要のあることの1つは、Unsafeクラスです。そのフルネームはsun.misc.Unsafeです。このクラスには、多くの直接メモリ割り当てやアトミック操作の呼び出しなど、Cコードに対する多数の操作が含まれています。安全ではないとマークされているのは、これで多数のメソッド呼び出しが安全上の問題を引き起こし、注意深く使用する必要があることを伝えることです。そうしないと、深刻な結果を引き起こします。たとえば、安全でない方法でメモリを割り当てる場合、特定のを指定すると自分で領域を作成すると、C ++に似たものが発生する可能性があります。ポインタは他のプロセスの範囲外です。

おすすめ

転載: blog.csdn.net/weixin_42120561/article/details/114241502