条件の機能は、ロックのより正確な制御を提供することです。条件のawait()メソッドはオブジェクトのwait()メソッド、条件の信号()メソッドはオブジェクトのnotify()メソッドに相当し、条件のsignalall()はオブジェクトのnotifyall()メソッドに相当します。違いは、オブジェクトのwait()、notify()、およびnotifyall()メソッドに「同期ロック」(同期キーワード)がバンドルされていることです。条件は、「Mutex」/「共有ロック」にバンドルする必要があります。
条件関数リスト
//現在のスレッドが信号を受信するか中断されるまで待機します。 void await()//は、信号を受信したり、中断されたり、指定された待機時間に到達してから、現在のスレッドが待機状態のままになります。 Booleanが待ち望んでいます(長い時間、TimeUnitユニット)//現在のスレッドは、信号を受信したり、中断されたり、指定された待機時間に到達するまで待機状態になります。 Long Waitnanos(Long Nanostimeout)//は、信号を受信する前に現在のスレッドを待機状態にします。 void awaituninterrumdibly()//現在のスレッドは、信号を受信したり、中断されたり、指定された締め切りに到達するまで待機状態にとどまります。 boolean awaituntil(日付の締め切り)//待っているスレッドを起こします。 void signal()//すべての待機スレッドを起動します。 void signalall()
条件クラスの使用例
条件は、オブジェクトモニターメソッド(待機、通知、および通知)をまったく異なるオブジェクトに分解し、これらのオブジェクトを任意のロック実装と組み合わせることにより、各オブジェクトが複数の待機セット(待機セット)を提供します。その中で、ロックは同期されたメソッドとステートメントの使用を置き換え、条件はオブジェクトモニターメソッドの使用を置き換えます。以下は、条件付きの実装とのスレッド通信の以前に書かれた例です。コードは次のとおりです。
public class threadtest2 {public static void main(string [] args){final business = new Business();新しいスレッド(new runnable(){@override public void run(){sweryexecute(business、 "sub");}})。start(); threadexecute(business、 "main"); } public static void threadexecute(business business、string threadtype){for(int i = 0; i <100; i ++){try {if( "main" .equals(threadtype)){business.main(i); } else {business.sub(i); }} catch(arturnedexception e){e.printstacktrace(); }}}} class business {private boolean bool = true;プライベートロックlock = new ReentrantLock();プライベートコンディション条件= lock.newcondition(); public /*同期* / void main(int loop)throws interruptedexception {lock.lock(); try {while(bool){condition.await(); // this.wait(); } for(int i = 0; i <100; i ++){system.out.println( "" + i + "のメインスレッドseq、" + loopのループ); } bool = true; condition.signal(); // this.notify(); }最後に{lock.unlock(); }} public /*synchronized* / void sub(int loop)throws arturtedexception {lock.lock(); try {while(!bool){condition.await(); // this.wait(); } for(int i = 0; i <10; i ++){system.out.println( "" + i + "のサブスレッドSeq、" + loop); } bool = false; condition.signal(); // this.notify(); }最後に{lock.unlock(); }}}条件では、wait()をwait()に置き換え、notify()をsignal()に置き換え、notifyall()をsignalall()に置き換えます。スレッドの従来の通信方法を実装できます。ここで、条件はロックにバインドされていることに注意してください。ロックを作成するには、newCondition()メソッドを使用する必要があります。
このようにして、状態は従来のスレッド通信と違いはありません。条件の力は、複数のスレッド間で異なる条件を確立できることです。以下は、説明するAPIのコードです。
class bundedbuffer {final lock = new ReentrantLock(); //ロックオブジェクト最終条件notfull = lock.newcondition(); // writeスレッド条件最終条件Notempty = lock.newcondition(); //読み取りスレッド条件[]項目= newオブジェクト[100]; 列*/; public void put(object x)throws arturtedexception {lock.lock(); try {while(count == items.length)//キューがnotfull.await(); //書き込みスレッド項目[putptr] = x; // if(++ putptr == items.length)putptr = 0; //書き込みインデックスが最後の位置に書かれている場合は、Queueの最後の位置に書かれている場合、スレッド}最後に{lock.unlock(); }} public object take()throws arturnedexception {lock.lock(); try {while(count == 0)//キューが空の場合はnotempty.await(); //読み取りスレッドオブジェクトx = items [takeptr]; //値を選択するif(++ rakeptr == items.length)takptr = 0; }最後に{lock.unlock(); }}}これは、マルチスレッド作業環境のキャッシュ領域です。キャッシュ領域には、2つの方法があります。データはデータを保存し、データを取得することであり、内部にキャッシュキューがあります。特定の変数とメソッドの説明については、コードを参照してください。このキャッシュ領域クラスによって実装された関数:複数のスレッドはデータを保存し、そこからデータを取得します。キャッシュキュー(最初は、最初は、最初に、次に、そして外出)がキャッシュが100になります。複数のスレッドは相互に排他的です。キャッシュキューに保存されている値が100に達すると、書き込みスレッドがブロックされ、読み取りスレッドが目覚めます。キャッシュキューに保存されている値が0の場合、読み取りスレッドがブロックされ、書き込みスレッドが目覚めます。コード実行プロセスの次の分析:
1.書き込みスレッドが実行され、Putメソッドを呼び出します。
2。カウントが100であるかどうかを判断するために、明らかに100はありません。
3.値を実行して預け続けます。
4.現在書かれているインデックス位置++を決定した後、100に等しいかどうか。書き込みインデックス値を0に均等にし、+1。
5.読み取りスレッドブロッキングキューの1つのみを覚ます。
6.読み取りスレッドを実行し、テイクメソッドを呼び出します。
7。…
8.書き込みスレッドブロッキングキューの1つだけを覚ます。
これが複数の条件の力です。キャッシュキューがいっぱいであると仮定すると、ブロッキングは間違いなく書き込みスレッドであり、ウェイクアップは間違いなく読み取りスレッドです。それどころか、ブロッキングは間違いなく読み取りスレッドであり、目覚めは間違いなく書き込みスレッドです。では、条件が1つしかない場合はどうなりますか?キャッシュキューはいっぱいです。このロックは、それが読み取りスレッドか書き込みスレッドかはわかりません。目覚めが読み取りスレッドである場合、誰もが幸せです。ウェイクアップが書き込みスレッドである場合、スレッドは目覚めて再びブロックされ、再び目覚めます。