1. JDKは、2つの非常に重要なスレッド・インターフェースを提供する、複数のスレッド間のコラボレーションをサポートするために:()メソッドは、通知が通知()メソッド待機を待ちます。
これらの2つの方法は、Threadクラスではありませんが、Objectクラスで出力。これは、任意のオブジェクトは、これら2つのメソッドを呼び出すことができることを意味します。
次のようにこれらの2つの方法があります
あなたがオブジェクトインスタンス()メソッドで待機呼び出すと、現在のスレッドがこのオブジェクトで待機します。
例えば、スレッドAは、と呼ばれるobj.wait()メソッドは、実行を停止するスレッドAは、待機状態に継続します。それが終了したときにそれを待ちますか?他のスレッドがこれまでobj.notity()メソッドを呼び出すまでスレッドが待機します。
2.wait()メソッドは、それを操作する方法を正確に()メソッドに通知しますか?
スレッドはObject.wait()メソッドを呼び出すと、それは待ち行列対象オブジェクトに入り、このキューは、システムは、オブジェクトを待つように同時に複数のスレッドを実行するために複数のスレッドが存在してもよいです
object.notify()メソッドが呼び出されると、それはスレッドを待っているキューからランダムに選ばれ、目を覚ますされます。
notity()メソッドに加えて、Objectオブジェクトは、類似してnotifyAll()メソッドを持っており、それがランダムではなく、待ち行列のすべての待機中のスレッドに目を覚ますだろうことを除いては、基本的に同じ機能notity方法です。
Object.wait()メソッドを呼び出すだけません。それはsynchronzied文オブジェクトに含まれている必要があり、どちらかを待つ()メソッドまたはnotity()メソッドは、最初の監視対象オブジェクトを取得する必要があります。
示されるようにT1とT2は、2つのスレッドを表し、T1は、右実行待ち()メソッドの前に、オブジェクトは、メソッドは、実行モニタを解除()監視対象であること、及びその後待たなければなりません。
目的は、オブジェクトのスレッドT1が寝ないであろうと、すべての正常を行うことができないので、他のオブジェクトを待っているようにすることです。
notity()メソッド内のスレッドT2は前に呼ばれ、それは、監視対象オブジェクトでなければなりません。このときT1は、モニターをリリースしました。したがって、T2は、オブジェクトを監視することができるオブジェクトを確保します。
その後、T2がウェイク-T1を想定し、この方法は、待機中のスレッドを起動しようとする)(通知実行、T1は、ウェイクアップ、後続のコードを実行するために最初に実行されず、再活性化しようとする試みであります
対象オブジェクトのモニターを取得し、T1はその待機中の()メソッドを保持する前に、このモニタも実行されます。
一時的に利用できない場合は、T1モニタを待つ必要があります。成功したモニターを取得した後、T1は、真の意味での実行を継続することができます。
理解を容易にするため、簡単な場合には3:
/ ** *待機和的学习通知 * @authorのWM * @date 2019年9月18日15時15 * / publicクラスSimpleWN { 最終的な静的オブジェクトのオブジェクト=新しいオブジェクト(); パブリック静的クラスT1は、拡張スレッド{ ます。public void実行(){ 同期(オブジェクト){ System.out.printlnは(のSystem.currentTimeMillis()+ ":!T1スタート"); System.out.println(のSystem.currentTimeMillis()+ ":オブジェクトのT1待ち"); {試みる はObject.waitを(); }キャッチ(InterruptedExceptionある電子){ e.printStackTrace(); } System.out.println(のSystem.currentTimeMillis()+ ":T1の終わり!"); } } } パブリック静的クラスT2は延びスレッド{ 公共ボイドラン(){ 同期(オブジェクト){ System.out.printlnは(のSystem.currentTimeMillis()+ ":開始T2つのスレッドを通知します")。 object.notify(); System.out.println(のSystem.currentTimeMillis()+ ":T2の終わり!"); {試みる はObject.waitを(); }キャッチ(InterruptedExceptionある電子){ e.printStackTrace(); } } } } パブリック静的無効メイン(文字列[] args){ スレッドT1 =新しいT1()。 スレッドT2 =新しいT2()。 t1.start(); t2.start(); } }
上記のコード、開いた二つのスレッドT1およびT2。T1ははObject.wait()メソッドを実行します。実行待ち()メソッドは、前に、T1は、最初のアプリケーションオブジェクトのロックオブジェクトです。
()はObject.wait行う場合したがって、オブジェクトロックオブジェクトによって保持されます。待機()メソッドを実行した後、T1が待機、およびオブジェクトロックオブジェクトを解放します。
2秒スリープT2ようnotityを行う前にT2()メソッドが最初にこの明確な結果を作るために、オブジェクトのロックオブジェクトを取得する、特別notity後()メソッドは、実行され、
そうすることでより明確T1通知notity()メソッドを得た後、説明することができる、またはオブジェクトのロックオブジェクトを回復しようと試みます。
結果:
1570675715571:T1を開始! 1570675715571:T1は待つためにオブジェクト 1570675715571:T2がスタート!一つのスレッドに通知 T2の終わり:1570675715571を! 1570675715571:T1の終わり!
T2 T1通知した後、続けてT1とすぐに進むことはできませんが、T2のロックオブジェクトのリリースを待つ、そして再び成功した後継続してロックします。
4.Object.wait()メソッドとのThread.sleep()メソッドは、いくつかの時間のためのスレッドを待機させることができ、待ち時間を除く()メソッドは、外部に起こされることができ、
もう一つの大きな違いは、ターゲットオブジェクトのロックを解除します待ち()メソッドで、のThread.sleep()メソッドは、すべてのリソースを解放しません。