条件与等待通知机制

2022-08-31 14:01:52

与传统的等待通知机制相比,使用条件接口/实现有什么优势?在这里,我引用Doug Lea撰写的评论:

条件将 Object monitor 方法(wait、notify 和 notifyAll)分解为不同的对象,通过将每个对象具有多个等待集与任意 Lock 实现结合使用,从而产生每个对象具有多个等待集的效果。如果 Lock 取代了同步方法和语句的使用,则 Condition 取代了对象监视器方法的使用。

我看到这是一种更面向对象的实现等待/通知机制的方式。但是,与前者相比,是否有合理的优势?


答案 1

最大的问题是等待/通知对于新开发人员来说容易出错。主要问题是不知道如何正确处理它们可能导致晦涩的错误。

  • 如果你在 wait() 之前调用 notify(), 它就会丢失。
  • 有时可能不清楚是否在同一对象上调用 notify() 和 wait()。
  • 等待/通知中没有任何内容需要状态更改,但在大多数情况下这是必需的。
  • wait() 可以虚假地返回

条件将此功能打包到专用组件中,但它的行为大致相同。

有一个关于等待/nofity的问题,在此之前几分钟发布,还有很多很多搜索[java]+wait+notify


答案 2

当您使用时,您可以区分哪个对象或对象/线程组获得特定信号。下面是一个简短的示例,其中一些线程(生产者)将获得信号,而消费者将获得信号:Condition: await()/signal()isEmptyisFull

private volatile boolean usedData = true;//mutex for data
private final Lock lock = new ReentrantLock();
private final Condition isEmpty = lock.newCondition();
private final Condition isFull = lock.newCondition();

public void setData(int data) throws InterruptedException {
    lock.lock();
    try {
        while(!usedData) {//wait for data to be used
            isEmpty.await();
        }
        this.data = data;
        isFull.signal();//broadcast that the data is now full.
        usedData = false;//tell others I created new data.          
    }finally {
        lock.unlock();//interrupt or not, release lock
    }       
}

public void getData() throws InterruptedException{
    lock.lock();
    try {
        while(usedData) {//usedData is lingo for empty
            isFull.await();
        }
        isEmpty.signal();//tell the producers to produce some more.
        usedData = true;//tell others I have used the data.
    }finally {//interrupted or not, always release lock
        lock.unlock();
    }       
}

推荐