What is communication between threads? How to realize thread communication

2.1 what is thread communication and implementation steps

There are two models of inter thread communication: shared memory and message passing
In fact, thread communication is to realize the alternating work of threads and transmit information

Specific steps of communication between threads: (involving upper, middle and lower parts)

Create a resource class in which ship attributes and operation methods are displayed
Operation methods in resource class: judgment, operation and notification
Create multiple threads and call the operation methods of the resource class
Prevent the problem of virtual wake-up (if interpretation, it will only be judged once)

2.2 synchronized cases

When operating a thread, the waiting thread uses wait()
Notify other thread operations with notify() and notifyAll()
Suppose there are two threads. In the process of execution, the thread judges the value (not the value to wait, let other threads grab), operates the value, and notifies the scheduling of another thread

Realize the operation of two threads on the value of num  one thread plus 1 and one thread minus 1, and implement it alternately for many times

//The first step is to create a resource class and define properties and operation methods
class Share {
    //Initial value
    private int num = 0;
    //+1 method
    public synchronized void incr() throws InterruptedException {
        //Step 2: judge the work notice
       if(number != 0) { //Judge whether the number value is 0. If not, wait
            this.wait(); //Wake up wherever you sleep
        }
        //If the number value is 0, the + 1 operation is performed
        number++;
        System.out.println(Thread.currentThread().getName()+" :: "+num);
        //Notify other threads
        this.notifyAll(); //Note that the notification here is random, that is, only all can be notified
    }
 
    //-1 method
    public synchronized void decr() throws InterruptedException {
        //judge
        if(number != 1) {
            this.wait();
        }
        //work
        number--;
        System.out.println(Thread.currentThread().getName()+" :: "+number);
        //Notify other threads
        this.notifyAll();
    }
}
 
public class ThreadDemo1 {
    //The third step is to create multiple threads and call the operation methods of the resource class
    public static void main(String[] args) {
        Share share = new Share();
        //Create thread
        new Thread(()->{
            for (int i = 1; i <=10; i++) {
                try {
                    share.incr(); //+1
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"AA").start();
 
        new Thread(()->{
            for (int i = 1; i <=10; i++) {
                try {
                    share.decr(); //-1
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"BB").start();
    }
}
 

You can see that at this time, the code is alternating, one + 1 and one thread - 1

But let's consider what happens if we add and subtract two threads at the same time?

False wake-up: wait , is where to sleep and where to be awakened. It is judged only once , false wake-up is put in while , if judgment, it will be judged only once, so it is changed to while; Circular judgment will solve the false awakening; To solve this error

2.3 Lock case

The lock object to be created and the lock object to be used first
Place in resource class

 
    private Lock lock= new ReentrantLock();   //Create a relocatable lock
    private Condition  condition= lock.newCondition();
        //The object he can operate

Lock lock();
Unlock lock unlock();
The following are condition classes:
Wake up all waiting threads, signalall(), with the class name condition signalAll();
Wake up a waiting thread signal (), with the class name, condition signal();
This causes the current thread to be in a waiting state await() with the class name, condition. Before receiving the signal or being interrupted await();

The code of Lock implementation is basically the same. Note that locking and unlocking are manually done by yourself. finally, they should be unlocked

If it is not unlocked, the following threads will be affected

class LShare{
//This is a shared resource. Pay attention to the creation and use of locks. Others are basically the same as above
    private int num=0;
 
    private Lock lock= new ReentrantLock();   //Create a relocatable lock
    private Condition  condition= lock.newCondition();
 
    //Method of creating operation
    public void add (){
        lock.lock();   //First, lock manually;
        try {  //Judge, work, inform
            while (num!=0){
                condition.await();
                //It uses this object to call the method and wait
            }
         num++;
            System.out.println( Thread.currentThread().getName()+" Work completion:"+num);
            condition.signalAll(); //This notification method
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
           lock.unlock(); //Eventually, no matter what error occurs, it will be unlocked
        }
    }

This realizes the communication between threads, that is, they can complete the alternating work according to the information

Here's how to customize communication? (alternate threads, but the work of each thread changes)

Keywords: JUC

Added by dmarchman on Mon, 07 Mar 2022 05:36:46 +0200