码迷,mamicode.com
首页 > 其他好文 > 详细

为什么wait和notify只能在synchronized中?

时间:2020-04-13 23:11:14      阅读:143      评论:0      收藏:0      [点我收藏+]

标签:产生   linked   情况   cpu   死锁   sem   code   必须   monit   

前言

wait和notify必须在synchronized块中,否则会抛出IllegalMonitorStateException。

原因

代码示例

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

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

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

代码示例的问题所在

一个消费者调用take,发现buffer.isEmpty。
在消费者调用wait之前,由于cpu的调度,消费者线程被挂起,生产者调用give,然后notify。
然后消费者调用wait (注意,由于错误的条件判断,导致wait调用在notify之后,这是关键)。
如果很不幸的话,生产者产生了一条消息后就不再生产消息了,那么消费者就会一直挂起,无法消费,造成死锁。

关键

总是让give/notify和take/wait为原子操作。wait/notify是线程之间的通信,他们存在竞态,我们必须保证在满足条件的情况下才进行wait。换句话说,如果不加锁的话,那么wait被调用的时候可能wait的条件已经不满足了(如上述)。由于错误的条件下进行了wait,那么就有可能永远不会被notify到,所以我们需要强制wait/notify在synchronized中。

为什么wait和notify只能在synchronized中?

标签:产生   linked   情况   cpu   死锁   sem   code   必须   monit   

原文地址:https://www.cnblogs.com/jichi/p/12694173.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!