スレッド通信は、スレッドの調整された動作を確保するために使用されます。一般に、スレッドの同期を行うときは、スレッド通信を考慮する必要があります。
1。従来のスレッド通信
通常、ObjectLtクラスによって提供される3つの方法が使用されます。
これらの3つの方法は、同期モニターオブジェクトによって呼び出され、2つの状況に分かれています。
同期する場合、同期モニターはこのオブジェクトであるため、これらの3つの方法を直接呼び出すことができます。
例は次のとおりです。
Public Class SyncMethodThreadCommunication {static class datawrap {int data = 0;ブールフラグ= false; public synchronized void addthreada(){if(flag){try {wait(); } catch(arturnedexception e){e.printstacktrace(); }} data ++; system.out.println(thread.currentthread()。getname() + "" + data); flag = true; notify(); } public synchronized void addthreadb(){if(!flag){try {wait(); } catch(arturnedexception e){e.printstacktrace(); }} data ++; system.out.println(thread.currentthread()。getname() + "" + data); flag = false; notify(); }} static class threada extends thread {private datawrap data; public threada(datawrap datawrap){this.data = datawrap; } @Override public void run(){for(int i = 0; i <10; i ++){data.addthreada(); }}} static class threadb extends thread {private datawrap data; public threadb(datawrap datawrap){this.data = datawrap; } @Override public void run(){for(int i = 0; i <10; i ++){data.addthreadb(); }}} public static void main(string [] args){// 2つのスレッドを実装してデータを追加してdatawrap datawrap = new Datawrap(); new threada(datawrap).start(); new Streadb(datawrap).start(); }}コードブロックを同期する場合、モニターオブジェクトを使用してこれらの3つのメソッドを呼び出す必要があります。
例は次のとおりです。
public class syncblockthreadcomminication {static class datawrap {boolean flag; INTデータ; } static class threada extends thread {datawrap datawrap; public threada(datawrap datawrap){this.datawrap = datawrap; } @Override public void run(){for(int i = 0; i <10; i ++){synchronized(datawrap){if(datawrap.flag){try {datawrap.wait(); } catch(arturnedexception e){e.printstacktrace(); }} datawrap.data ++; system.out.println(getname() + "" + datawrap.data); datawrap.flag = true; datawrap.notify(); }}}}} static class threadb extends thread {datawrap datawrap; public Streadb(datawrap datawrap){this.datawrap = datawrap; } @Override public void run(){for(int i = 0; i <10; i ++){synchronized(datawrap){if(!datawrap.flag){try {datawrap.wait(); } catch(arturnedexception e){e.printstacktrace(); }} datawrap.data ++; system.out.println(getname() + "" + datawrap.data); datawrap.flag = false; datawrap.notify(); }}}} public static void main(string [] args){// 2つのスレッドを実装してデータを追加してdatawrap datawrap = new Datawrap(); new threada(datawrap).start(); new Streadb(datawrap).start(); }}2。条件を使用して、スレッド通信を制御します
ロックオブジェクトを使用して同期を確保する場合、調整を確実にするために条件オブジェクトが使用されます。
例は次のとおりです。
import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;import com.sun.media.sound.RIFFInvalidDataException;import javafx.scene.chart.PieChart.Data;public class SyncLockThreadCommunication {静的クラスDATAWRAP {int data;ブールフラグ;プライベートファイナルロックロック= new ReentrantLock();プライベート最終条件= lock.newcondition(); public void addthreada(){lock.lock(); try {if(flag){try {condition.await(); } catch(arturnedexception e){e.printstacktrace(); }} data ++; system.out.println(thread.currentthread()。getname() + "" + data); flag = true; condition.signal(); }最後に{lock.unlock(); }} public void addthreadb(){lock.lock(); try {if(!flag){try {condition.await(); } catch(arturnedexception e){e.printstacktrace(); }} data ++; system.out.println(thread.currentthread()。getname() + "" + data); flag = false; condition.signal(); }最後に{lock.unlock(); }}} static class threada extends thread {datawrap datawrap; public threada(datawrap datawrap){this.datawrap = datawrap; } @Override public void run(){for(int i = 0; i <10; i ++){datawrap.addthreada(); }}} static class threadb extends thread {datawrap datawrap; public Streadb(datawrap datawrap){this.datawrap = datawrap; } @Override public void run(){for(int i = 0; i <10; i ++){datawrap.addthreadb(); }}} public static void main(string [] args){// 2つのスレッドを実装してデータを追加してdatawrap datawrap = new Datawrap(); new threada(datawrap).start(); new Streadb(datawrap).start(); }}条件オブジェクトのawait()、singal()、およびsingalall()は、それぞれwait()、notify()、およびnotifyall()メソッドに対応します。
3.ブロッキングキューブロッキングキューを使用して、スレッド通信を制御します
BlockingQueueは、主にスレッド通信に使用されるキューインターフェイスのサブインターフェイスです。機能があります。プロデューサーのスレッドがブロッキングキューに要素を入れようとすると、キューがいっぱいの場合、スレッドがブロックされます。消費者のスレッドがブロックキューから要素を取り除こうとすると、キューが空の場合、スレッドはブロックされます。これらの2つの機能は、ブロッキングをサポートする2つの方法に対応しています。
例は次のとおりです。
java.util.concurrent.arrayblockingqueue;インポートjava.util.concurrent.blockingqueue; public class blockingqueuethreadcomminication {static class datawrap {int data; } static class threada extends thread {private blockingqueue <datawrap> blockingqueue;パブリックスレッド(blockingqueue <datawrap> blockingqueue、string name){super(name); this.blockingQueue = blockingqueue; } @Override public void run(){for(int i = 0; i <100; i ++){try {datawrap datawrap = blockockingqueue.take(); datawrap.data ++; system.out.println(getname() + "" + datawrap.data);睡眠(1000); } catch(arturnedexception e){e.printstacktrace(); }}}}} static class threadb extends thread {private blockingqueue <Datawrap> blockingqueue;プライベートダトーラップダトーラップ;パブリックスレッド(BlockingQueue <Datawrap> blockingqueue、datawrap datawrap、string name){super(name); this.blockingQueue = blockingqueue; this.datawrap = datawrap; } @Override public void run(){for(int i = 0; i <100; i ++){try {datawrap.data ++; system.out.println(getname() + "" + datawrap.data); blockingqueue.put(datawrap);睡眠(1000); } catch(arturnedexception e){e.printstacktrace(); }}}} public static void main(string [] args){/// 2つのスレッドを実装してデータを追加してdatawrap datawrap = new Datawrap(); blockingqueue <datawrap> blockingqueue = new arrayblockingqueue <>(1);新しいThreada(BlockingQueue、 "Consumer")。start(); new StreadB(BlockingQueue、DataWrap、 "Producer")。start(); }}BlockingQueueには5つの実装クラスがあります。
配列の実装に基づいて、arrayblockingqueue blockingqueueキュー
LinkedBlockingQueueリンクリストに基づいてBlockingQueueキュー
PriorityBlockingQueueの要素は、比較可能なインターフェイスを実装する必要があり、要素の順序付けはComparatorによってカスタマイズされています。
Synchronousqueueはキューを同期するため、キューのアクセス操作を交互に実行する必要があります。
Delayqueueコレクション要素は、遅延インターフェイスを実装する必要があり、キュー内の要素は、遅延インターフェイスメソッドgetDelay()の戻り値に従ってソートされます。
上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。