java同步中条件变量和条件谓词的区别

apa*_*ana 5 java concurrency synchronization

我正在寻找一个带有解释的示例来理解 java 中条件变量和条件谓词之间的区别。

这是在同步的上下文中。

另外,我想知道这些术语是否是在 Java 文档中找到的实际 Java 术语,还是其他作者参考了这些术语?

为了进一步澄清问题,请考虑以下示例(取自 Java Concurrency 书籍):

@ThreadSafe
public class BoundedBuffer<V> extends BaseBoundedBuffer<V> {

    public BoundedBuffer(int size) { super(size); }

    // BLOCKS-UNTIL: not-full
    public  synchronized  void put(V v) throws InterruptedException {
        while (isFull())
            wait();
        doPut(v);
        notifyAll();
    }

    // BLOCKS-UNTIL: not-empty
    public  synchronized  V take() throws InterruptedException {
        while (isEmpty())
            wait();
        V v = doTake();
        notifyAll();
        return v;
    } 
}
Run Code Online (Sandbox Code Playgroud)

什么是条件变量,什么是条件谓词?您可能有比这更好、更简单的示例来解释差异。我很困惑每个人究竟指的是什么(条件变量与谓词),无论它们是否相同。

了解 Java 低级并发的人可能是回答这个问题的最佳人选。

Stu*_*rks 3

条件变量是由操作系统或线程系统提供的构造,它提供等待通知操作并维护一组等待线程。

条件谓词是由使用条件变量的代码调用或实现的谓词(布尔值函数或表达式)。简而言之,线程等待条件变量,直到谓词为真,并且当谓词为真时,线程通知(或发信号)条件变量。

换句话说,条件谓词是用于测试对象逻辑状态的代码,而条件变量是在正在更改对象状态和等待对象更改状态的线程之间进行通信的机制。

该示例代码有些令人困惑,因为它使用两个具有相同条件变量的条件谓词。执行put的线程测试isFull谓词(它不必是函数;它可以是布尔表达式),执行take 的线程测试isEmpty谓词。它们都使用相同的条件变量,即与this缓冲区对象关联的条件变量。请注意,while 循环中测试的条件是谓词的逆条件。执行put操作的线程会等待,直到谓词为 true,因此代码会谓词不为 true 时等待。

术语“条件谓词”似乎没有标准化。这是一个合理的描述性术语,Goetz 在《Java 并发实践》中使用了它。在 Lampson 和 Redell 的《Mesa 中的进程和监视器的经验》中,他们大多只使用术语“谓词”。(Java 的对象监视器几乎是 Mesa 的精确副本。Pthreads 也非常相似。)我还看到了使用的术语前置条件状态谓词

条件变量这个术语是这个结构的一个相当标准的术语。它被 Mesa 和 Pthreads 使用,并且可能可以追溯到 Hoare 最初的监视器工作。奇怪的是,Java 规范很少使用这个术语;它们只是指与每个对象关联的监视器,并且它可以被锁定、解锁、等待或通知。然而,包中有一个Condition接口和实现java.util.concurrent.locks。该Condition接口代表一个条件变量。