How to prove that sleep does not release the lock, but wait releases the lock?

Wait locking example

public class WaitDemo {
    private static Object locker = new Object();

    public static void main(String[] args) throws InterruptedException {
        WaitDemo waitDemo = new WaitDemo();

        // 启动新线程,防止主线程被休眠
        new Thread(() -> {
            try {
                waitDemo.doWait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
        Thread.sleep(200); // 此行本身没有意义,是为了确保 wait() 先执行再执行 notify()
        waitDemo.doNotify();
    }

    /**
     * 执行 wait()
     */
    private void doWait() throws InterruptedException {
        synchronized (locker) {
            System.out.println("wait start.");
            locker.wait();
            System.out.println("wait end.");
        }
    }

    /**
     * 执行 notify()
     */
    private void doNotify() {
        synchronized (locker) {
            System.out.println("notify start.");
            locker.notify();
            System.out.println("notify end.");
        }
    }
}

The results of the above procedures are:

Code parsing

As can be seen from the above code, we put the same lock on the wait () and notify () methods, but the lock is released after calling the wait () method, so the program can execute the notify () code normally, because it is the same lock. If the lock is not released, the notify () code will not be executed, This can also be confirmed from the printed results (the output order of the results), so the wait () method releases the lock.

Sleep locking example

public class WaitDemo {
    private static Object locker = new Object();

    public static void main(String[] args) throws InterruptedException {
        WaitDemo waitDemo = new WaitDemo();
        // 启动新线程,防止主线程被休眠
        new Thread(() -> {
            synchronized (locker) {
                try {
                    System.out.println("sleep start.");
                    Thread.sleep(1000);
                    System.out.println("sleep end.");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();

        Thread.sleep(200);
        waitDemo.doNotify();
    }

    /**
     * 执行 notify()
     */
    private void doNotify() {
        synchronized (locker) {
            System.out.println("notify start.");
            locker.notify();
            System.out.println("notify end.");
        }
    }
}

The results of the above procedures are:

Code parsing

It can be seen from the above code that after the execution of sleep (1000) method (line number: 11), the notify () method was not acquired to the locker lock, which can be seen from the above execution results, but the notify () method that was executed after the sleep (1000) method was executed. Therefore, it is proved that the calling sleep () method does not release the lock.

Knowledge expansion

1. What is the difference between sleep and wait?

Sleep and wait are necessary questions in almost all interviews, but it seems that it is not so easy to answer them correctly.

The usual answer to the difference between sleep and wait is:

However, the above answer obviously misses an important difference. After calling the wait method, the thread will change to waiting state, while after calling the sleep method, the thread will change to timed_ Waiting status.

2. Can wait be used in static method? Why?

No, because the wait method is an instance method (not a static method), it cannot be used in static. The source code is as follows:

public final void wait() throws InterruptedException {
    wait(0);
}

3. Can wait / notify not be used with synchronized? Why?

No, because if it is not used with synchronized, the program will report an error, as shown in the following figure:

The deeper reason is that without synchronized, it will cause lost wake-up problem. For details, see: https://juejin.im/post/5e6a4d8a6fb9a07cd80f36d1

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>