WAT-NOTIFYシーン
典型的なWait-Notifyシーンは、一般に次の2つの内容に関連しています。
1。状態変数
スレッドが待機する必要がある場合、それは常にいくつかの条件によって引き起こされます。たとえば、キューの要素がいっぱいの場合、キューに入力すると、スレッドは実行を停止する必要があります。キュー要素が空いたら、独自の実行を続けます。
2。状態述語
スレッドがnotifyから待機を入力するか目覚めするかを決定した場合、ステータス条件が満たされているかどうかをテストする必要があります。たとえば、キューに要素を追加すると、キューは完全であるため、他のスレッドがキューから要素を取り除くと、「キュー」はキューに残りのスペースがあります。糸。"現時点では、要素を待つプロセスが目覚め、実際に現在のキューがある場合は、要素を追加します。次のウェイク-Up。
3。条件キュー
各オブジェクトには、スレッドがオブジェクトの待機関数を呼び出すと、スレッドがオブジェクトの条件キューに追加されます。
知らせ
待って、通知はJava同期メカニズムの重要な部分です。同期されたキーワードの使用と組み合わせて、プロデューサー - 消費者モデルなど、多くの優れた同期モデルを確立できます。ただし、function()、notify()、notifyall()functionを使用する場合、次のポイントに特に注意を払う必要があります。
wait()、notify()、notifyall()メソッドはスレッドクラスに属するのではなく、オブジェクトファンデーションクラスに属します。つまり、各オブジェクトにはwait()、notify()、およびnotify()の関数があります。各オブジェクトはロックされているため、ロックは各オブジェクトの基礎であるため、操作ロックの方法も最も基本的です。
OBJのwait()およびNotify()メソッドを呼び出します。OBJロックを取得する必要があります。つまり、同期(OBJ){...}コードセグメントに記述する必要があります。
obj.wait()を呼び出した後、スレッドAはOBJのロックを解放します。そうしないと、スレッドBはOBJロックを取得できず、同期(obj){...}コードでスレッドAを覚ますことができませんセグメント。
obj.wait()メソッドが返されると、実行を継続するためにOBJロックを再度取得する必要があります。
スレッドa1、a2、a3がobj.wait()にある場合、スレッドbはobj.notify()を呼び出します。
スレッドBがobj.notifyall()を呼び出す場合、彼はすべて待っているスレッドA1、A2、A3を目覚めることができますが、obj.wait()の次の文を実行し続けるための待機スレッドは、OBJロックを取得する必要があります。したがって、スレッドA1、A2、A3は、ロックを取得して実行し続ける可能性が1つだけです。
スレッドBはobj.notify()またはobj.notifyall()を呼び出すと、スレッドBはobjロックを保持していますが、a3は目覚めますが、objロックは取得できません。スレッドBが同期コードブロックを終了してOBJロックをリリースするまで、スレッドA1、A2、A3に1つはオブジェクトロックを取得して実行し続ける機会があります。
たとえば、コード
スレッドの待機操作の典型的なコード構造は次のとおりです。
public void test()throws arturnedexception {synchronized(obj){while(!contidition){obj.wait();}}}}}}}}}}}}}}}}}}}}}}}
なぜobj.wait()操作がサイクルに配置されなければならないのですか?いくつかの主な理由があります:
1.オブジェクトロックは、複数の状態変数を保護するために使用できます。たとえば、特定のオブジェクトは、2つのステータス変数aとBを保護するために、アサーションの条件が確立されていない場合、待機操作が発生します。状態変数aの操作が発生すると、notifyall操作がOBJで呼び出され、OBJに対応する条件キューのすべてのスレッドが目覚めている必要はありません。この時点でもBが目覚めているため、Bの状態が満たされるかどうかをリサイクルする必要があります。
2。複数のスレッドの同じ状態の条件が主張されています。たとえば、キューに要素を追加するシーン、現在のキューはいっぱいであり、複数のスレッドが内部に要素を追加したいので、それらはすべてです。現時点では、別のスレッドがキューから要素を取り出し、すべてのスレッドを目覚めさせるためにnotifyall操作を呼び出しましたが、他のスレッドを待機する必要があるスレッドは1つだけです。
3。誤った目覚め。通知されることなく、割り込みOROUTでは、スレッドは自動的に目覚めました。この状況は実際にはめったに発生しませんが、この状況はサイクル待機によって排除される可能性があります。