Brief analysis of synchronized principle and realization principle of waiting notification mechanism in Java object

What is the waiting notification mechanism in concurrent programming? In short, one thread modifies the value of an object, and another thread perceives the change, and then performs the corresponding operation. In the previous blog , the use of LockSupport and Condition of Java JUC Concurrent Package Components , we introduced the waiting notification mechanism implemented using the queue synchronizer. In this article, we introduced the waiting notification mechanism of Java objects implemented using synchronized, and the related waiting/notification Methods are available for any Java object, because these methods are defined on the superclass java.lang.Object of all objects. The methods and descriptions are shown in the following table:

Method name

description

wait()

The thread that calls this method enters the WAITING state, and returns only when it waits for another thread’s notification or is interrupted. Note that the object’s lock will be released after the wait method is called

wait(long)

Wait for a while, if there is no notification, it will time out and return. The parameter is milliseconds

wait(long, int)

More fine-grained control of the timeout period, up to nanoseconds

notify()

Notify a thread waiting on the object to return from the wait method, and the premise of the return is that the thread has acquired the lock of the object

notifyAll()

Notify all threads waiting on the object

The above method: a thread A calls the wait() method of the object O to enter the waiting state, and another thread B calls the notify() or notifyAll() method of the object O, and the thread A receives the notification from the wait() of the object O ) Method returns, and then performs subsequent operations. This is the waiting notification mechanism of Java objects. These methods need to be used with synchronized. First, we first introduce the implementation principle of synchronized. The keyword synchronized can modify the method or use it in the form of a synchronized block. It mainly ensures that multiple threads can only be in a method or synchronization block at the same time. It ensures the visibility and exclusivity of thread access to variables.

In the previous introduction to the use of synchronized, it has been introduced that any object has its own monitor. When this object is called by the synchronization block or the synchronization method of this object, the thread executing the method must first obtain the monitor of the object before it can enter synchronization. Block or synchronization method, but did not obtain the monitor (execute the method) thread will be blocked at the entrance of the synchronization block and synchronization method, enter the BLOCKED state, the following figure describes the object, object monitor, synchronization queue and The relationship between execution threads:

 Any thread's access to an Object (Object is protected by synchronized) must first obtain the Object monitor. If the acquisition fails, the thread enters the synchronization queue, and the thread status becomes BLOCKED. When the predecessor of accessing the Object (the thread that acquired the lock) releases the lock, the release operation wakes up the thread blocked in the synchronization queue and makes it retry the acquisition of the monitor. Here is no longer introducing the use of synchronized, you can refer to the security of the blog thread and the use of synchronized and lock upgrade .

Previously we introduced the internal implementation of synchronized. Below we introduce the implementation of the waiting notification mechanism for Java objects. Compared with the synchronized implementation, the waiting notification mechanism is implemented on the basis of the synchronized implementation, and the process is more complicated. Let's first write an example of waiting for notification, the code is as follows:

public class WaitNotify {
    static boolean flag = true;
    static Object lock = new Object();
    public static void main(String[] args) throws Exception {
	//等待线程
	Thread waitThread = new Thread(new Wait(), "WaitThread");
	waitThread.start();
	TimeUnit.SECONDS.sleep(1);
	//通知线程
	Thread notifyThread = new Thread(new Notify(), "NotifyThread");
	notifyThread.start();
    }

    static class Wait implements Runnable {
        public void run() {
	    // 加锁,拥有lock的Monitor
	    synchronized (lock) { 
		// 当条件不满足时,继续wait,同时释放了lock的锁
		while (flag) {
		    try {
		        System.out.println("WAITING 线程启动并且执行");
		        //调用wait方法,线程进入WAITING状态
			lock.wait();
		    } catch (InterruptedException e) {
					}
		} // 条件满足时,完成工作
            }
            System.out.println("收到 notify通知,获取对象监视器,继续执行");
        }
    }

    static class Notify implements Runnable {
	public void run() {
	    // 加锁,拥有lock的Monitor
	    synchronized (lock) { 
            // 获取lock的锁,然后进行通知,通知时不会释放lock的锁, 
	    System.out.println("通知线程启动");
	    //通知其他处理WAITING状态的线程
	    lock.notifyAll();
	    flag = false;
	    }
	}
    }
}

From the above example, we can see that the wait/notification mechanism of Java objects relies on the synchronization mechanism, whose purpose is to ensure that the waiting thread can perceive the modification of the variable made by the notification thread when it returns from the wait() method. In the above example, WaitThread first acquires the lock of the object, and then calls the wait() method of the object, thereby giving up the lock and entering the WaitQueue of the object, entering the waiting state. Because WaitThread releases the object's lock, NotifyThread subsequently acquires the object's lock and calls the object's notify() method to move the WaitThread from the WaitQueue to the SynchronizedQueue. At this time, the state of the WaitThread becomes blocked. After NotifyThread releases the lock, WaitThread acquires the lock again and returns from the wait() method to continue execution. The following is its state transition flowchart:

Guess you like

Origin blog.csdn.net/wk19920726/article/details/108710059