この記事では、主に、次のように、Java並行性条件ブロッキング条件のアプリケーションサンプルコードを研究しています。
条件は、オブジェクトモニターメソッド(待機、通知、および通知)をまったく異なるオブジェクトに分解し、これらのオブジェクトを任意のロック実装と組み合わせることにより、各オブジェクトが複数の待機セット(待機セット)を提供します。その中で、ロックは同期されたメソッドとステートメントの使用を置き換え、条件はオブジェクトモニターメソッドの使用を置き換えます。
条件を使用して、待機、通知、その他の方法を交換できるため、前に書かれたスレッド間通信コードを比較し、元の問題を確認できます。
2つのスレッドがあります。子スレッドは最初に10回実行され、次にメインスレッドが5回実行され、その後、子スレッドに切り替えて10が実行され、メインスレッドは5回実行されます...この往復は50回です。
以前に待機して通知して通知しましたが、今では条件を使用して書き換えました。コードは次のとおりです。
public class conditionCommunication {public static void main(string [] args){business business = new business(); new runnable(){//子スレッド@Override @Override public void run(){for(int i = 1; i <= 50; i ++){bussiness.sub(i);}}}}; i < 50; i ++){bussiness.main(i);}}} class business {lock = new reentrantlock(); condition = lock.newcondition(); //条件は、特定のロックブールのbshouldsub = true; {condition.await(); //条件を使用してawait method} catch(例外e)を呼び出す(// todo auto-generated catch blocke.printstacktrace();}} for false; condition.signal(); //条件を使用してウェイクアップ信号を送信し、特定の1つを目覚めさせる}最後に{lock.unlock();}} public void main(int i){lock.lock(); try {while(bshouldsub){try {condition.await(); blocke.printstacktrace();}} for(int j = 1; j <= 10; j ++){system.out.println( "" + j + "のメインスレッドシーケンス、" + j + "のループ、} bshouldsub = true; condition.signal();コードの観点から、条件はロックと一緒に使用されます。ロックがなければ、条件はロックを介して作成されるため、状態を使用できません。この使用法は非常に簡単です。同期の使用を習得している限り、待機し、通知する限り、ロックと状態の使用を完全にマスターできます。
上記は、同期されたオブジェクトモニターメソッドの代わりにロックと状態を使用して、2つのスレッド間の通信を実現します。次に、少し高度なアプリケーションを書きましょう。バッファのブロッキングキューをシミュレートします。
バッファとは何ですか?たとえば、今すぐメッセージを送信したい人がたくさんいます。私はトランジットステーションであり、他の人がメッセージを送信するのを手伝いたいと思っています。だから今、私は2つのことをする必要があります。 1つのことは、ユーザーから送信されたメッセージを受信し、それらをバッファに整理することです。もう1つは、バッファーから順番にユーザーから送信されたメッセージを取り出して送信することです。
この実際の問題を抽象化する:バッファーは配列です。配列にデータを書き込むか、配列からデータを取り出すことができます。私がしなければならない2つのことは、データを取得するためにデータを保存するために2つのスレッドを開始することです。しかし、問題は、バッファーがいっぱいの場合、メッセージが受信されすぎる、つまり送信されたメッセージが速すぎることを意味し、私の人生の別のスレッドはそれを送信するのに十分ではないことを意味し、バッファーが除外されるため、データストレージのスレッドをブロックして待機させる必要があります。それどころか、私がそれを速すぎると、バッファのすべての内容が私から送信され、ユーザーが新しいメッセージを送信していない場合、現時点ではデータ取得のスレッドをブロックする必要があります。
OK、このバッファのブロッキングキューを分析した後、コンディションテクノロジーを使用して実装しましょう。
class Buffer {final lock = new ReentrantLock(); // Lock Final Condition notfull = lock.newcondition(); // define conditionfinal条件Notempty = lock.newcondition(); // define conditionfinalオブジェクト[]項目= newオブジェクト[10]; // count; // array subscriptsは、ポジションデータをqueueに格付けデータを調整するために使用されます。存在!到達した場合、最初にputptr = 0; ++ count; //メッセージシステムの数に戻ります。空のキューでスレッドを起動すると、データを取得できます}最終的に{lock.unlock(); // lock}} // queue public objectection()throws interrupedex.lock(); // lock try {while(count == 0){count == 0){system.out.Out.Out.OUT.println(swread.currentthread.currentthread.currentthread for()時間がある! system.out.println(thread.currentthread()。getname() + "get out out out out out:" + x); notfull.signal(); //わかりました、今ではキューに場所があります。キューでいっぱいのスレッドを起こすと、データを保存できます。 x;}最後に{lock.unlock(); // lock}}}}を返しますこのプログラムは古典的なものです。公式のJDKドキュメントから取り出してコメントを追加しました。プログラムには2つの条件が定義されており、2つのスレッドを実行し、それぞれ待機して目を覚ますために使用されます。アイデアは明確で、プログラムも非常に堅牢です。 1つの質問を考慮することができますが、なぜ2つのコードを使用する必要があるのですか?このデザインには理由がなければなりません。条件を使用する場合、キューがいっぱいであると仮定しますが、同時にデータを保存する2つのスレッドAとBがあり、それらはすべて睡眠に入ります。 OK、別のスレッドが1つを取り除いてから、スレッドAの1つを目覚めさせ、Aが保存できます。保存後、別のスレッドを目覚めさせます。 Bが目覚めた場合、この時点でキューがいっぱいで、Bが保存できないため、問題が発生します。 Bが貯蔵する場合、取得されていない値を上書きします。条件が使用されるため、貯蔵と撤退の両方がこの状態を使用して眠り、目覚めます。この時点で、この状態の使用を理解できます。次に、上記のブロッキングキューの効果をテストしましょう。
public class boundedbuffer {public static void main(string [] args){buffer buffer = new buffer(); for(int i = 0; i <5; i ++){// 5スレッドを開き、新しいスレッドにデータを保存する(new runnable(){@Override public void run(){try {buffertint(); (arturnedexception e){e.printstacktrace();}}})。 {e.printstacktrace();}}})。start();}}}}}}}データの取得をブロックするだけで、データとデータを取得するためにデータと10個のスレッドを保存するために5つのスレッドのみを意図的に有効にしました。
スレッド5はブロックされており、当面はデータを取得できません!
Thread-10はブロックされており、当面はデータを取得できません!
スレッド1保存値:755
スレッド-0保存値:206
スレッド2保存値:741
スレッド-3保存値:381
スレッド14削除値:755
スレッド4保存値:783
スレッド-6値を取り出します:206
スレッド7削除値:741
スレッド8削除値:381
スレッド9値を取り出します:783
スレッド5はブロックされており、当面はデータを取得できません!
スレッド11はブロックされており、当面はデータを取得できません!
スレッド12はブロックされており、当面はデータを取得できません!
Thread-10はブロックされており、当面はデータを取得できません!
スレッド13はブロックされており、当面はデータを取得できません!
結果から、スレッド5と10が最初に実行され、キューには存在しないことがわかるので、ブロックされて眠ります。新しい値がキューに保存されるまでのみそれを取得できます。ただし、それらは幸運ではなく、保存されたデータは最初に他のスレッドによって取得されます。ハハ...彼らはそれをもう数回実行できます。保存されているデータがブロックされているのを確認する場合は、スレッドを設定してデータを少し少なくすることができます。ここでは設定しません。
以前と同じ質問です。次に、3つのスレッドを実行させます。質問を見てみましょう。
3つのスレッドがあり、子スレッド1は最初に10回実行され、チャイルドスレッド2は10回実行し、メインスレッドは5回実行し、子スレッド1は10回実行し、子スレッド2は10回実行し、メインスレッドは5回実行されます...この往復は50回です。
条件を使用しない場合は、非常に難しいですが、状態で行うのは非常に便利です。原則は非常に単純です。 3つの条件を定義します。チャイルドスレッド1が実行された後、チャイルドスレッド2がメインスレッドを目覚めさせ、メインスレッドが子スレッド1を目覚めます。以下のコードを見てみましょう。理解しやすいです。
public class threeconditionCommunication {public static void main(string [] args){business business = new business(); new runnable(){//子スレッド@Override @Override public void run(){for {//別の子スレッドを起動する@Override public void run(){for(int i = 1; i <= 50; i ++){bussiness.sub2(i);}}}})条件1 = lock.newcondition(); //条件は条件2 = lock.newcondition();条件条件= lock.newcondition(); private int bshouldsub = 0; public void sub1(int i){lock.lock(); try {while {while(bshouldsub!= 0){try {try {try {condition1.await(); {// todo auto-generated catch blocke.printstacktrace();}} for(int j = 1; j <= 10; j ++){system.out.println( " + j +"のsub1スレッドシーケンス、 " + i);} bshouldsub = 1; dysonig {lock.unlock();}} public void sub2(int i){lock.lock(); try {while(bshouldsub!= 1){try {condition2.await(); // await methodを呼び出すために条件を使用する} catch(例外E){// dodo auto-generated catch blockke.printstrace( j ++){System.out.println( "" + j + "のsub2スレッドシーケンス、" + i);} bshouldsub = 2; conditionmain.signal(); // let let let let let let let let let let {lock.unlock();}} public void main {conditionmain.await(); //条件を使用してawait methodを呼び出す} catch(例外e){//(int j = 1; j <= 5; j ++){system.out.print.println( " + j + j + j + j + j + j + i + i + i + i + iの主要なスレッドシーケンス{int j <= 5; j ++){system.out.println( 0; condition1.signal(); // thread 1 execute}最後に{lock.unlock();}}}}}}}}コードは少し長いように見えますが、それは幻想であり、ロジックは非常に簡単です。これは、スレッドの条件技術を要約するためのすべてです。
上記は、Java Concurrency条件ブロッキング条件のアプリケーションコードの例に関するこの記事の内容全体です。私はそれが誰にでも役立つことを願っています。興味のある友人は、このサイトの他の関連トピックを引き続き参照できます。欠点がある場合は、それを指摘するためにメッセージを残してください。このサイトへのご支援をありがとうございました!