マルチスレッドのインタビューの質問(2020)

マルチスレッド
1.並列と並行の違いは何ですか?
並列:複数のタスクが細分化されたタイムスライスで(交互に)同じCPUコアで実行されます。論理的には、これらのタスクは同時に実行されます。
同時実行性:複数のプロセッサまたはマルチコアプロセッサが複数のタスクを同時に処理します。
以下に示すように:
並行および並行並行= 2つのキューとコーヒーマシン。パラレル= 2つのキューと2つのコーヒーマシン。

2.スレッドとプロセスの違いは何ですか?
プログラムの実行速度を上げるために、1つのプログラムの下に少なくとも1つのプロセス、1つのプロセスの下に少なくとも1つのスレッド、および1つのプロセスの下に複数のスレッドがあります。

3.デーモンスレッドとは何ですか?
デーモンスレッドは、バックグラウンドで実行される特別なプロセスです。制御端末とは独立しており、定期的に特定のタスクを実行するか、特定のイベントの発生を待ちます。Javaでは、ガベージコレクションスレッドは特別なデーモンスレッドです。

4.スレッドを作成する方法は何ですか?
スレッドを作成するには、スレッドの再実行メソッドを継承する方法、Runnableインターフェイスを実装する方法、Callableインターフェイスを実装する方法の3つがあります。

5.実行可能と呼び出し可能の違いは何ですか?
runnableには戻り値がありません。callableは戻り値を取得できます。callableはrunnableの補足と見なすことができます。

6.スレッドの状態はどうですか?
スレッドの状態:NEWは開始されていません
RUNNABLEが実行されていますBLOCKEDブロック(同期ロックまたはIOロックがブロックされました)WAITING永久待機状態TIMED_WAITING指定された時間が再開するまで待機しますTERMINATED実行が完了しました

7.スリープ()と待機()の違いは何ですか?
異なるクラス:sleep()はThreadから、wait()はObjectから。ロックを解放します:sleep()はロックを解放しません; wait()はロックを解放します。使い方は異なります:スリープ()はタイムアップ時に自動的に回復します;待機()は、通知()/通知()を使用して直接起動できます。

8. notify()とnotifyAll()の違いは何ですか?
notifyAll()はすべてのスレッドを起動し、notify()はスレッドを起動します。
notifyAll()が呼び出された後、すべてのスレッドが待機プールからロックプールに移動され、ロックの競合に参加します。競合が成功した場合、スレッドは引き続き実行されます。競合が成功しなかった場合、ロックプールに留まり、ロックが解放されて再び競合に参加するのを待ちます。
Notify()は、1つのスレッドのみを起動します。このスレッドは、仮想マシンによって明確に制御されます。

9.スレッドのrun()とstart()の違いは何ですか?
start()メソッドを使用してスレッドを開始し、run()メソッドを使用してスレッドのランタイムコードを実行します。run()は繰り返し呼び出すことができますが、start()は一度しか呼び出すことができません。

10.スレッドプールを作成するいくつかの方法は何ですか?
スレッドプールを作成する方法は7つあり、コアが最後の方法です
。newSingleThreadExecutor():ワーカースレッドの数が1に制限されており、***ワークキューを操作しているため、すべてのタスクが確実に実行されます。順次実行されると、最大で1つのタスクがアクティブになり、ユーザーはスレッドプールインスタンスを変更できないため、スレッド数の変更を回避できます;
newCachedThreadPool():これは、多数の短時間の作業タスクを処理するために使用されるスレッドプールです、いくつかの特徴的な機能があります:スレッドをキャッシュして再利用します。キャッシュスレッドが使用できない場合は、新しいワーカースレッドを作成します。スレッドが60秒以上アイドル状態の場合、スレッドは終了し、キャッシュから移動します。長時間アイドル状態になると、この種類のスレッドプールはリソースを消費しません。SynchronousQueueは内部的にワークキューとして使用されます; newFixedThreadPool(int nThreads):指定された数のスレッド(nThreads)を再利用します。その背後で***ワークキューが使用され、いつでも最大nThreadsワーカースレッドがアクティブになります。つまり、タスクの数がアクティブなキューの数を超えると、アイドルスレッドがワークキューに表示されるのを待ちます。ワーカースレッドが終了すると、新しいワーカースレッドが作成され、指定された数のnThreadsを作成します
。newSingleThreadScheduledExecutor():シングルスレッドプールを作成し、スケジュールされたまたは定期的な作業のスケジューリングのためにScheduledExecutorServiceに戻ります。
newScheduledThreadPool(int corePoolSize):newSingleThreadScheduledExecutor()と同様に、スケジュールされたまたは定期的な作業スケジューリングを実行できるScheduledExecutorServiceを作成します。違いは、単一のワーカースレッドか複数のワーカースレッドか、newWorkStealingPool(int並列処理)です:これは頻繁ですスレッドプールを無視し、Java 8はこの作成メソッドのみを追加しました。内部的にForkJoinPoolを構築し、Work-Stealingアルゴリズムを使用してタスクを並行して処理します。処理順序は保証しません;
ThreadPoolExecutor():は、上記の1- 3作成メソッドはすべてThreadPoolExecutorのカプセル化です。

11.スレッドプールの状態は何ですか?
実行中:これは最も正常な状態であり、待機キュー内の新しいタスクと処理タスクを受け入れます。
シャットダウン:新しいタスクの送信を受け入れませんが、待機キュー内のタスクの処理を続行します。
STOP:新しいタスクの送信を受け入れず、待機キュー内のタスクを処理せず、タスクを実行しているスレッドを中断します。
TIDYING:すべてのタスクが破棄され、workCountが0で、スレッドプールの状態がTIDYING状態に変更され、フックメソッド終了()が実行されます。
TERMINATED:terminate()メソッドが終了すると、スレッドプールの状態はこれになります。スレッドプールのsubmit()メソッドとexecute()メソッドの違いは何ですか?execute():Runnableタスクのみを実行できます。
submit():RunnableタスクとCallableタスクを実行できます。
呼び出し可能なタスクは実行の戻り値を取得できますが、Runnableの実行には戻り値がありません。
12. Javaプログラムでマルチスレッド操作の安全性を確保する方法は?
方法1:Java。Util。Concurrentのクラスなどのセキュリティクラスを使用します。
方法2:同期された自動ロックを使用します。
方法3:手動ロックを使用します。手動ロックのJavaコードは次のとおりです:Lock lock = new ReentrantLock(); lock。Lock(); try {System。Out。Println(“ Acquire lock”);} catch(Exception e){// TODO:handle exception}最後に{System。Out。Println( "Release lock"); lock。Unlock();
}

  1. マルチスレッドでの同期ロックエスカレーションの原理は何ですか?
    同期ロックアップグレードの原則:ロックオブジェクトのオブジェクトヘッダーにthreadidフィールドがあります。初めてアクセスされるとき、threadidは空です。jvmは、バイアスされたロックを保持し、threadidをそのthreadidに設定します。再び入ると、最初に、スレッドIDがスレッドIDと一致しているかどうかを判断します。一致している場合は、このオブジェクトを直接使用できます。一致していない場合、アップグレードバイアスロックは軽量ロックです。ロックは、特定の数のスピンサイクルを通じて取得されます。使用するオブジェクトを取得すると、ロックは軽量ロックから重量ロックにアップグレードされます。このプロセスは、同期ロックのアップグレードを構成します。ロックアップグレードの目的:ロックアップグレードは、ロックによって引き起こされるパフォーマンスの消費を減らすことです。Java 6の後で同期化の最適化された実装は、バイアスロックのアップグレードを使用して軽量ロックに、次に重量ロックにアップグレードすることで、ロックのパフォーマンスコストを削減します。
    14.デッドロックとは何ですか?
    スレッドAが排他ロックaを保持し、排他ロックbを取得しようとすると、スレッドBが排他ロックbを保持し、排他ロックaを取得しようとすると、2つのスレッドABが互いに保持する必要がある場合があります。発生するブロッキング現象をデッドロックと呼びます。
    15.デッドロックを防ぐには?
    tryLock(長いタイムアウト、TimeUnitユニット)メソッド(ReentrantLock、ReentrantReadWriteLock)の使用を試み、タイムアウト期間を設定します。タイムアウトは、デッドロックを防ぐために終了できます。独自の手書きロックの代わりに、Java。Util。同時並行クラスを使用してみてください。ロックの細分性を減らし、同じロックをいくつかの機能に使用しないようにしてください。同期するコードブロックの数を最小限に抑えます。
    16. ThreadLocalとは何ですか?使用シナリオは何ですか?
    ThreadLocalは、変数を使用するスレッドごとに変数の独立したコピーを提供するため、各スレッドは、他のスレッドに対応するコピーに影響を与えることなく、独自のコピーを個別に変更できます。ThreadLocalの典型的な使用シナリオは、データベース接続とセッション管理です。
    17.同期の基本的な実装原理は何ですか?
    Synchronizedは、monitorenter / monitorexit命令のペアによって実装され、monitorオブジェクトは同期の基本単位です。Java 6より前は、モニターの実装はオペレーティングシステム内のミューテックスに完全に依存していました。ユーザーモードからカーネルモードに切り替える必要があるため、同期操作は重量操作であり、違いはなく、パフォーマンスも非常に低くなります。Java 6のは、Javaは仮想マシンが大きい行われたときにでも、
    ナイフ広い斧の改善を、多くの場合、三つの異なるロックと言われる三つの異なるモニターの実装を、提供:ロックバイアス(偏りロック)、軽量等級ロックと重量ロックは、パフォーマンスを大幅に改善しました。
    18.同期型と揮発性の違いは何ですか?
    volatileは変数修飾子で、synchronizedは変更されたクラス、メソッド、およびコードセグメントです。揮発性は変数の変更された可視性のみを達成でき、原子性は保証できませんが、同期は変数の変更された可視性と原子性を保証できます。volatileはスレッドブロッキングを引き起こしません。
    19.同期とロックの違いは何ですか?
    synchronizedはクラス、メソッド、およびコードブロックをロックできます; lockはコードブロックのみをロックできます。Synchronizedは、手動でロックを取得および解放する必要はありません。使用方法は簡単です。例外が発生した場合、自動的にロックが解放され、デッドロックは発生しません。ロック自体がロックを追加および解放する必要があります。ロック。ロックを通じて、ロックを正常に取得したかどうかを知ることができますが、同期はそれを行うことができません。20.同期とReentrantLockの違いは何ですか?
    同期の初期実装は比較的非効率的です。ReentrantLockと比較すると、ほとんどのシナリオのパフォーマンスはかなり異なりますが、Java 6では同期同期が大幅に改善されています。主な違いは次のとおりです。ReentrantLockはより柔軟に使用できますが、ロックを解放するアクションと連携する必要があります。ReentrantLockは手動でロックを取得および解放する必要があり、同期は手動でのロックの解放とロック解除を必要としません。ReentrantLockはコードブロックロックにのみ適用され、同期は変更に使用できます。メソッド、コードブロックなど volatileとマークされた変数は、コンパイラーによって最適化されません。synchronizedとマークされた変数は、コンパイラーによって最適化できます。
  2. 原子の原理について教えてください。
    atomicは主にCAS(比較およびWwap)と揮発性およびネイティブのメソッドを使用してアトミック操作を保証し、同期の高いオーバーヘッドを回避し、実行効率を大幅に向上させます。

おすすめ

転載: blog.51cto.com/14760318/2486660