スレッド間のコラボレーションは、どのように達成するために?
1.ポーリング:タイムリーに、大きなリソースのオーバーヘッドを確保することが困難です
2、待機および通知
待機と通知の標準パラダイム:
広場待っ:
ロックオブジェクトを取得するために行く、
その後、ループ条件で判断することはwaitメソッドを呼び出すことに満足、満足していません。
条件は、ビジネスロジックの実装満たされた
通知パーティー:
オブジェクトのロックを取得
変更の条件は
、すべてのスレッドオブジェクトで待っ通知します
3.方法:
待って():ロック取得対象を待って
待機(1000):タイムアウトが一定時間以上待って待機していません。
通知:スレッドの通知
のnotifyAllをすべて同じロック・スレッドを待っていることを通知
二、join()メソッド
1、インタビューの質問:持っているスレッドAとスレッドB、そのスレッドBを確保する方法は、スレッドAを実行した後に実行する必要がありますか?
方法1:()参加し
たCountDownLatchの:方法2
参加スレッドBを実行するための方法をスレッド、スレッドBのA後のスレッドが実行を待たなければならない場合は以上です、スレッドAが自分の仕事を続けることができます:説明。
サンプルコード:join()メソッドとオフ、スレッドの実行優先度を可能にします
/ * * *デモに参加()メソッド * / パブリック クラスUseJoin2 { 静的 クラススレッド{拡張JumpQueue @Override 公共 のボイドRUNを(){ のために(int型 I = 0 ;私は< 5。 、私は++ ){ システム。OUT .printlnを(" ステップ実行している現在のスレッド「 + I)を、 試み{ のThread.sleep(1000年); } キャッチ(InterruptedExceptionあるE){ e.printStackTrace(); } } } } パブリック 静的 ボイドメイン(文字列[]引数){ システム。OUT .println(" メインメソッドに------> " ); JumpQueue jumpQueue = 新しい新しいJumpQueue(); jumpQueue .setName(" joinThread " ); jumpQueue.start(); // jumpQueue.join()メソッド:jumpQueueスレッドが前にメインスレッドを実行する 試み{ jumpQueue.join(); } キャッチ(InterruptedExceptionあるE){ e.printStackTrace(); } システム。OUT .println(" メインスレッドは、ビジネス・ロジックの処理を開始する" ); 試み{ のThread.sleep(500 ); } キャッチ(InterruptedExceptionあるE){ e.printStackTrace(); } 。システムOUT .printlnを(「メインスレッドが終了すると、ビジネス・ロジックを処理しますA " ); } }
三、収量()、スリープ() 、(通知)、()を待つとロックに影響する他の方法
)の実行利回り(後のスレッドは、ロックが解除されていない保持している
ロックを保持、睡眠()メソッドを呼び出した後解放されていない
()待ち:待機()メソッドを呼び出す前に、ロックを保持しておく必要があります。呼び出しの後()メソッドを待ちます。waitメソッドの戻りは、ロックを保持しているスレッドが再うと、ロックは、(仮想マシンをリリース)リリースされる
呼び出す前に、私たちがロックを保持する必要があります。)(通知します。ロックを解除しないであろう通知()メソッド自体を呼び出すだけ同期コード・ブロックは、ロックプレイ解放する前に実行された
のnotifyAllを())(通知と
など、:公共ボイドchangeKm同期(){
this.km = 101;
(通知)/このコード行を実行したときに/、ロックはこの時点で解放されていません。
System.out.println(「ビジネスロジック」); //この行の実装後に終了し、ロックを解除。
}
図1に示すように、サンプルコード:ロックを保持した後にスリープ()メソッドの呼び出しが解除されていない識別
/ * * *検証睡眠()メソッドは、スレッドを解放しませんロックが眠っている スレッドがロックを取得する場合は、その後、睡眠を睡眠します*。他のスレッドがロックを取得することはできません、だけで待つことができます * / パブリック クラスSleepLock { プライベートオブジェクトをロック = 新しい新しいオブジェクトを(); // スレッドクラス眠る プライベート クラスはスレッド{拡張ThreadSleep @Override 公共 無効RUN(){ 文字列のthreadNameを = にThread.currentThread()のgetName();. // ロックを取得しようとする システムを。OUT .println(のthreadName + " ロックの取得しよう" ); 試してみます{ 同期(ロック){ システム。OUT .println(のthreadName + 「ロックがかかっている」); // スレッドの後にロックを取得するために、睡眠5秒 のThread.sleep(5000 ); 。システムOUT .println(「フィニッシュザ・作業:" + のthreadName); } } キャッチ(InterruptedExceptionあるE){ } } } // ない休眠スレッドクラス プライベート クラスThreadNotSleepはスレッド{延び @Override 公共 ボイドラン(){ 文字列のthreadName = にThread.currentThread()のgetNameを()。 // 尝试去拿锁 システム。アウト .println(のthreadNameは+ " ロックの時間を取るようにしてみてください= " + にSystem.currentTimeMillis()); 同期(ロック){ システム。アウト .println(のthreadNameは+ " ロック時間を割い= " + にSystem.currentTimeMillis()); システム。アウト .println(「作業を終了し、」 + )のthreadName。 } } } パブリック 静的 ボイドメイン(文字列[]引数){ SleepLock sleepLock = 新しいSleepLock()。 // 会休眠的线程 スレッドthreadSleep = sleepLock。新しいThreadSleep(); threadSleep.setName(" threadSleep " ); // 不会休眠的线程 スレッドthreadNotSleep = sleepLock。新しいThreadNotSleep(); threadNotSleep.setName(" threadNotSleep " ); threadSleep.start(); threadNotSleep.start(); } }
2、サンプルコード:待ち()メソッドを呼び出した後、ロックが解除されます
パブリック クラスThreadDomain31は、Thread {拡張 プライベートオブジェクトのロックを。 公共 ThreadDomain31(物体オブジェクト){ この。ロック = オブジェクトを。 } @Override 公共 無効実行(){ しようと{ 同期(ロック) { システム。アウト .println(にThread.currentThread()のgetName()+。" )(待機を開始します" ); ロック .WAITを(); システム。でる.println(にThread.currentThread()のgetName()+。" 終了待ち" )。 } } キャッチ(InterruptedExceptionある電子){ e.printStackTrace(); } } }
パブリック クラスのテスト{ 公共 静的 ボイドメイン(文字列[]引数){ / * * *出力: *スレッド0は、ウェイト()開始 スレッド待ち1(開始)。 wait()をロックを解除する、または単に入口スレッド2 * / オブジェクトロック = 新しい新しいオブジェクト(); ワークシートThreadDomain31のMT0 = 新しい新しい ThreadDomain31(ロック); ThreadDomain31 MTL = 新しい新しい ThreadDomain31(ロック); mt0.start(); mt1.start(); } }
3、古典的な生産者、消費者のモデルは、通知/待っ実証します