专注于 JetBrains IDEA 全家桶,永久激活,教程
持续更新 PyCharm,IDEA,WebStorm,PhpStorm,DataGrip,RubyMine,CLion,AppCode 永久激活教程

为什么wait/notify必须要强制要求放在synchronized中

1 为什么wait/notify必须要强制要求放在synchronized中

在日常开发,我们都知道wait/notify有着非常固定的一套模板,就是下面的样子,synchronized同步块包裹着Object.wait()方法,如果不通过同步块包住的话JVM会抛出IllegalMonitorStateException异常。

synchronized(lock) {
    while(!condition){
        lock.wait();
    }
}

那么为什么要限制这么写呢?

2 如果Object.wait()/notify不需要同步

假设我们自己实现了一个BlockingQueue的代码。 如果Object.wait()/notify不需要同步,那么我们的代码会形如下面这样。

class BlockingQueue {
    Queue<String> buffer = new LinkedList<String>();

    public void give(String data) {
        buffer.add(data);
        notify();                   // 往队列里添加的时候notify,因为可能有人在等着take
    }

    public String take() throws InterruptedException {
        while (buffer.isEmpty())    // 用while,防止spurious wakeups(虚假唤醒)
            wait(); // 当buffer是空的时候就等着别人give
        return buffer.remove();
    }
}

如果上面的代码可以执行的话,多线程情况下会出现一种情况:

1、 当前buffer是空的,这时来了一个take的请求,尚未执行到wait语句
2、 同时又来了一个give请求,完整执行完了整个give方法并且发送了notify
3、 此时take方法才走到wait,因为它错过了上一个notify,所以会在明明buffer不空的情况下挂起线程,take方法挂起。假如再没有人调用过give方法了,在业务上的表现就会是这个take线程永远也取不到buffer中的内容 56_1.png

3 为什么要在JVM层面抛异常

因为你只要用notify,那就是为了在多线程环境下同步,notify/wait机制本身就是为了多线程的同步而存在的,那就只能配套synchronized,所以为了防止上面情况的发生,就直接强制抛异常来限制开发的代码模式了。

4 如果没有wait/notify

试想一种场景,如果没有wait/notify的挂起唤醒机制,该如何实现BlockingQueue

class BlockingQueue {
    Queue<String> buffer = new LinkedList<String>();

    public void give(String data) {
        buffer.add(data);
    }

    public String take() throws InterruptedException {
        while(buffer.isEmpty) {
            sleep(10);
        }
        return buffer.remove();
    }
}

如果没有wait/notify,那么在take的时候只能通过while循环不停轮询判断buffer是否为空来实时获取buffer的最新状态,那么势必会造成两种情况:

1、 sleep时间过短,那么线程将一直不行循环抢占CPU,造成CPU打满
2、 sleep时间过长,那么将会影响take的时效性

综上,针对于BlockingQueue这样的场景,同步块 + wait/notify 或者 lock + signal/await 就是标配

文章永久链接:https://tech.souyunku.com/28512

未经允许不得转载:搜云库技术团队 » 为什么wait/notify必须要强制要求放在synchronized中

JetBrains 全家桶,激活、破解、教程

提供 JetBrains 全家桶激活码、注册码、破解补丁下载及详细激活教程,支持 IntelliJ IDEA、PyCharm、WebStorm 等工具的永久激活。无论是破解教程,还是最新激活码,均可免费获得,帮助开发者解决常见激活问题,确保轻松破解并快速使用 JetBrains 软件。获取免费的破解补丁和激活码,快速解决激活难题,全面覆盖 2024/2025 版本!

联系我们联系我们