java - 条件给出了每个对象有多个等待集的效果?

标签 java multithreading conditional-statements reentrantlock

我正在阅读 java.util.concurrent.locks.Condition 中的条件。

Condition factors out the Object monitor methods (wait, notify and notifyAll) >into distinct objects to give the effect of having multiple wait-sets per object, by combining them with the use of arbitrary Lock implementations.

有人能给我解释一下吗?

这与普通同步块(synchronized block)或方法相比有何优势?

最佳答案

一个锁可以关联多个条件。锁是一个“对象”,每个条件都是一个“等待集”。这允许独立条件共享临界区。例如,考虑有界生产者-消费者问题。解决它的一种方法是有一个保护队列的锁,以及两个独立的等待集:一个用于生产者,等待槽将项目放入队列中,另一个用于等待项目被拿走的消费者。使用普通的旧 synchronizedwait/notify API,我们能做的最好是沿着这些路线:

  • 制作人:

    synchronized (lock) {
        while (queue.isFull()) {
            lock.wait();
        }
        queue.put(sth);
        lock.notify();
    }
    
  • 消费者:

    synchronized (lock) {
        while (queue.isEmpty() {
            lock.wait();
        }
        product = queue.take();
        lock.notify();
    }
    

这有一个缺点,即在队列每次更改时都会唤醒生产者和消费者,即使它不可能允许给定的线程继续进行(例如,当其他消费者从队列)。使用 Lock/Condition API,我们可以实现将等待的消费者和生产者分开的解决方案,从而减少冗余的唤醒和检查:

Lock lock = new ReentrantLock();
Condition hasPlace = lock.newCondition();
Condition hasItems = lock.newCondition();
  • 制作人:

    lock.lock();
    try {
        while (queue.isFull()) {
            hasPlace.await();
        }
        queue.put(sth);
        hasItems.signal();
    } finally {
        lock.unlock();
    }
    
  • 消费者:

    lock.lock();
    try {
        while (queue.isEmpty()) {
            hasItems.await();
        }
        product = queue.take();
        hasPlace.signal();
    } finally {
        lock.unlock();
    }
    

这样,消费者等待生产者生产一些元素(hasItems 条件),并在从队列中删除一个元素时通知生产者有一个空槽(hasPlace 条件)。这两种情况都与相同的临界区(锁)相关联,因此我们保留了通常的排除和等待时释放锁的保证,同时获得了分离等待队列的能力。

关于java - 条件给出了每个对象有多个等待集的效果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18490636/

相关文章:

python - 同步函数内的 asyncio.run 返回 None

java - 如何将列表转换为 map ?

java - 从 Java webapp 子目录提供静态文件

java - 如何从Stripe API中的收费对象中扣除申请费?

java - 如何在 Netty channel 处理程序中安全地执行阻塞操作?

python - 处理另一个线程中的异常

java - 寻找竞争条件

c++ - 有关条件 block 的问题与&&运算符有关

python - 根据列值选择用户 - pandas dataframe

java - 由于 JAXBException : IllegalAnnotationExceptions,实现 GET REST 服务时出现问题