Thread communication is used to ensure that threads are coordinated, and it is generally necessary to consider the problem of thread communication when doing thread synchronization.
1. Traditional thread Communication
Typically, the three methods provided by the OBJECLT class are used:
- Waiting () causes the current thread to wait and releases the lock on the synchronization monitor until the other thread calls the synchronization Monitor's notify () or Notifyall () method to wake the thread.
- Notify (), wakes up the thread waiting on this synchronization monitor, if more than one will arbitrarily select a wakeup
- Notifyall () wakes up all the threads waiting on this synchronization monitor, which, after scheduling competing resources, acquires a lock on the synchronization monitor and then runs.
These three methods must be called by the synchronization monitor object and are divided into two situations:
When synchronizing a method, you can call these three methods directly because the synchronization monitor is the this object.
Examples are as follows:
public class Syncmethodthreadcommunication {static class datawrap{int data = 0;
Boolean flag = false;
Public synchronized void Addthreada () {if (flag) {try {wait ();
catch (Interruptedexception e) {e.printstacktrace ();
}} data++;
System.out.println (Thread.CurrentThread (). GetName () + "" + data);
Flag = true;
Notify ();
Public synchronized void addthreadb () {if (!flag) {try {wait ());
catch (Interruptedexception 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 < 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 < i++) {data.addthreadb ();
}} public static void Main (string[] args) {//enable two threads to rotate the data by one operation Datawrap datawrap = new Datawrap ();
New Threada (Datawrap). Start ();
New Threadb (Datawrap). Start ();
}
}
When you synchronize a code block, you need to use the monitor object to invoke these three methods.
Examples are as follows:
public class Syncblockthreadcomminication {static Class datawrap{Boolean flag;
int data;
Static class Threada extends thread{datawrap datawrap;
Public Threada (Datawrap datawrap) {this.datawrap = Datawrap;
@Override public void Run () {(int i = 0; i < i++) {synchronized (datawrap) {
if (Datawrap.flag) {try {datawrap.wait ();
catch (Interruptedexception e) {e.printstacktrace ();
}} datawrap.data++;
System.out.println (GetName () + "" + datawrap.data);
Datawrap.flag = true;
Datawrap.notify ();
"}}} static class Threadb extends thread{datawrap datawrap;
Public threadb (Datawrap datawrap) {this.datawrap = Datawrap; @Override public void Run () {for (int i = 0; i < i++) {SynchronizEd (datawrap) {if (!datawrap.flag) {try {datawrap.wait ();
catch (Interruptedexception e) {e.printstacktrace ();
}} datawrap.data++;
System.out.println (GetName () + "" + datawrap.data);
Datawrap.flag = false;
Datawrap.notify (); }}} public static void Main (string[] args) {//Implement two threads to take turns to add one operation to the data datawrap data
Wrap = new Datawrap ();
New Threada (Datawrap). Start ();
New Threadb (Datawrap). Start ();
}
}
2. Using condition to control thread communication
When a lock object is used to guarantee synchronization, the condition object is used to guarantee coordination.
Examples are as follows:
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 {static class Datawrap {int data;
Boolean flag;
Private Final lock lock = new Reentrantlock ();
Private final Condition Condition = Lock.newcondition ();
public void Addthreada () {lock.lock ();
try {if (flag) {try {condition.await ();
catch (Interruptedexception e) {e.printstacktrace ();
}} data++;
System.out.println (Thread.CurrentThread (). GetName () + "" + data);
Flag = true;
Condition.signal ();
finally {Lock.unlock ();
} public void Addthreadb () {lock.lock ();
try {if (!flag) {try { Condition.await ();
catch (Interruptedexception e) {e.printstacktrace ();
}} data++;
System.out.println (Thread.CurrentThread (). GetName () + "" + data);
Flag = false;
Condition.signal ();
finally {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 < i++) {Datawrap.addthreada ();
}} static Class Threadb extends thread{datawrap datawrap;
Public threadb (Datawrap datawrap) {this.datawrap = Datawrap;
@Override public void Run () {for (int i = 0; i < i++) {datawrap.addthreadb (); }} public static void Main (string[] args) {//enable two threads to rotate data in turn datawrap datawrap = new DatawRap ();
New Threada (Datawrap). Start ();
New Threadb (Datawrap). Start ();
}
}
Where the condition object's await (), Singal (), Singalall () correspond to the wait (), the Notify (), and the Notifyall () method respectively.
3, using blocking queue Blockingqueue control thread communication
Blockingqueue is a sub-interface of the queue interface, used primarily for thread communication, and has a feature: when a producer thread tries to put an element into the Blockingqueue, the thread is blocked if the queue is full When a consumer thread attempts to remove an element from the Blockingqueue, the thread is blocked if the queue is empty. These two features correspond to two methods that support blocking, put (e E) and take ()
Examples are as follows:
Import Java.util.concurrent.ArrayBlockingQueue;
Import Java.util.concurrent.BlockingQueue;
public class Blockingqueuethreadcomminication {static class datawrap{int data;
Static class Threada extends thread{private blockingqueue<datawrap> blockingqueue;
Public Threada (blockingqueue<datawrap> blockingqueue, String name) {super (name);
This.blockingqueue = Blockingqueue; @Override public void Run () {for (int i = 0; i < i++) {try {datawrap dat
Awrap = Blockingqueue.take ();
datawrap.data++;
System.out.println (GetName () + "" + datawrap.data);
Sleep (1000);
catch (Interruptedexception e) {e.printstacktrace ();
The static class Threadb extends thread{private blockingqueue<datawrap> blockingqueue;
Private Datawrap Datawrap; Public threadb (blockingqueue<datawrap> BlockiNgqueue, Datawrap datawrap, String name) {super (name);
This.blockingqueue = Blockingqueue;
This.datawrap = Datawrap; @Override public void Run () {(int i = 0; i < i++) {try {DataWrap.dat
a++;
System.out.println (GetName () + "" + datawrap.data);
Blockingqueue.put (Datawrap);
Sleep (1000);
catch (Interruptedexception e) {e.printstacktrace (); '}} ' public static void main (string[] args) {///implements two threads to add one operation to the data datawrap Datawrap = NE
W Datawrap ();
blockingqueue<datawrap> blockingqueue = new arrayblockingqueue<> (1);
New Threada (Blockingqueue, "Consumer"). Start ();
New Threadb (Blockingqueue, Datawrap, "Producer"). Start ();
}
}
There are five implementation classes in Blockingqueue:
Arrayblockingqueue Blockingqueue queues based on array implementations
Linkedblockingqueue Blockingqueue queue based on linked list implementation
Elements in the priorityblockingqueue need to implement the comparable interface, where the ordering of the elements is ordered according to comparator.
The Synchronousqueue synchronization queue requires that the access to the queue be performed alternately.
The Delayqueue collection element must implement the delay interface, and the sorting of the elements in the queue is sorted according to the return value of the Delay interface method Getdelay ().
The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.