03-3 inter thread communication Object waitnotify

Keywords: Java

wait/notify wait notification method

The wait notification mechanism is that the thread in the waiting state will be notified by other threads to obtain CPU resources again and continue to perform tasks that have not been completed before. The most typical example is the producer consumer model

If the producer wants to add products to the queue, the consumer needs to take products out of the queue. If the queue is empty, the consumer should wait for the producer to add products before consuming. When the queue is full, the producer needs to wait for the consumer to consume some products before continuing production. Queues can be considered as critical resources in the java model. Producers and consumers think they are different threads. They need to occupy critical resources alternately to execute their own methods, so they need inter thread communication.

The wait / notify mechanism mainly provides three methods for communication between threads

wait() the current thread releases the lock and enters the wait (blocking) state

notify() wakes up a thread waiting for the corresponding object lock and puts it into the ready queue to continue competing for the lock after the current thread releases the lock

notifyAll() wakes up all threads waiting for the corresponding object lock to enter the ready queue to continue competing for the lock after the current thread releases the lock

The wait / notify mechanism means that one thread A calls the wait() method of the Object to enter the wait state, while the other thread B calls the notify() or notifyAll() method of the Object. When thread A receives the notification, it can return from the wait() method of the Object to perform subsequent operations. The communication between threads needs to be completed by the Object. The wait (), notify (), notifyAll () methods in the Object are like switch signals, which are used to complete the interaction between the waiting party and the notifying party.

Relevant methods of waiting / notification:

example

Scenario - two threads. One thread adds 1 to the current value, and the other thread subtracts 1 to the current value. A total of 10 times

Suppose that the initial value of this shared variable is 0, one thread t1 pair value + 1, and the other thread t2 pair value - 1

package com.dongguo.concurrent.waitnotify;

/**
 * @author Dongguo
 * @date 2021/9/3 0003-13:15
 * @description: bounded-buffer problem 
 * Scenario --- two threads. One thread adds 1 to the current value, and the other thread subtracts 1 to the current value. A total of 10 times
 * Suppose that the initial value of this shared variable is 0, one thread pair value + 1, and the other thread pair value - 1
 */
public class ThreadWaitNotifyDemo {
    public static void main(String[] args) {
        Number number = new Number();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                number.incry();
            }
        }, "t1").start();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                number.decry();
            }
        }, "t2").start();
    }
}

class Number {
    private int count;

    public synchronized void incry() {
        if (count != 0) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        count++;
        System.out.println(Thread.currentThread().getName() + "Plus one success, count The value is:" + count);
        this.notifyAll();
    }

    public synchronized void decry() {
        if (count == 0) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        count--;
        System.out.println(Thread.currentThread().getName() + "Minus one, count The value is:" + count);
        this.notifyAll();
    }
}

Operation results:

t1 Plus one success, count Value: 1
t2 Minus one, count Value: 0
t1 Plus one success, count Value: 1
t2 Minus one, count Value: 0
t1 Plus one success, count Value: 1
t2 Minus one, count Value: 0
t1 Plus one success, count Value: 1
t2 Minus one, count Value: 0
t1 Plus one success, count Value: 1
t2 Minus one, count Value: 0
t1 Plus one success, count Value: 1
t2 Minus one, count Value: 0
t1 Plus one success, count Value: 1
t2 Minus one, count Value: 0
t1 Plus one success, count Value: 1
t2 Minus one, count Value: 0
t1 Plus one success, count Value: 1
t2 Minus one, count Value: 0
t1 Plus one success, count Value: 1
t2 Minus one, count Value: 0

Details to pay attention to when calling wait(), notify() and notifyAll(),.
1) When using wait(), notify() and notifyAll(), you need to lock the calling object first.
2) After calling the wait() method, the thread state changes from RUNNING to WAITING, and the current thread is placed in the object
Wait queue.
3) After the notify() or notifyAll() method is called, the waiting thread still does not return from wait(). You need to call notify() or
After the thread of notifAll() releases the lock, the waiting thread has the opportunity to return from wait().
4) The notify() method moves a waiting thread in the waiting queue from the waiting queue to the synchronization queue, and notifyAll()
The method is to move all threads in the WAITING queue to the synchronization queue, and the state of the moved thread changes from WAITING to
BLOCKED.
5) The precondition for returning from the wait() method is to obtain the lock of the calling object.
As can be seen from the above details, the wait / notify mechanism relies on the synchronization mechanism, and its purpose is to ensure that the waiting thread from
When the wait() method returns, it can sense the changes made by the notification thread to the variables.

Posted by altergothen on Fri, 19 Nov 2021 18:43:25 -0800