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)

  1. Create a resource class in which ship attributes and operation methods are defined
  2. Operation methods in resource class: judgment, operation and notification
  3. Create multiple threads and call the operation methods of the resource class
  4. 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 threads with notify() and notifyAll()
Suppose there are two threads. During the execution of the thread, judge the value (not the value to wait, let other threads grab), operate the value, and notify the scheduling of another thread

Two threads can operate on the value of num  one thread plus 1 and one thread minus 1, which can be implemented 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 wake up. It is judged only once , false wake-up is put in while , if judgment, it will only judge once, so it is changed to while; Circular judgment will solve the false awakening; To solve this error

2.3 Lock case

To use lock, you must first create the object of the lock and the object of the notification
Place in resource class

    private Lock lock= new ReentrantLock();   //Create a relocatable lock
    private Condition  condition= lock.newCondition();
        //He can manipulate the object

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 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? (threads alternate, but the work of each thread changes)

 

Keywords: Java Back-end thread

Added by andycole on Tue, 14 Dec 2021 13:06:41 +0200