条件是否为每个对象提供多个等待集? [英] Condition give the effect of having multiple wait-sets per object?

查看:158
本文介绍了条件是否为每个对象提供多个等待集?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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


条件因素将对象监视器方法(wait,notify和notifyAll)>分解为不同的对象,以通过将它们与使用任意Lock $ b相结合来实现每个对象具有多个
等待集的效果$ b实现。

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.

有人能解释一下吗?

这是怎么回事是否优于普通同步块或方法?

How this is a benefit over normal synchronization blocks or method?

推荐答案

一个锁可以与许多条件相关联。锁是一个对象,每个条件都是等待集。这允许共享关键部分的独立条件。例如,考虑有限的生产者 - 消费者问题。解决这个问题的一种方法是拥有一个保护队列的锁,以及两个独立的等待集:一个用于生产者,等待插槽将项放入队列,另一个用于等待物品采取的消费者。使用普通的 synchronized wait / notify API,我们可以做的最好的就是这些:

One Lock can be associated with many Conditions. Lock is an "object", each condition is a "waiting set". This allows for independent conditions sharing critical section. For example, consider bounded producers-consumers problem. One way to solve it is to have one lock that protects the queue, and two independent waiting sets: one for producers, waiting for slot to place item in the queue, other for consumers waiting for items to take. Using plain old synchronized and wait/notify API, best we can do is along these lines:


  • 生产商:

  • producer:

synchronized (lock) {
    while (queue.isFull()) {
        lock.wait();
    }
    queue.put(sth);
    lock.notify();
}


  • 消费者:

  • consumer:

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


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

    This has the disadvantage of waking up both producers and consumers on every change to the queue, even if it cannot possibly allow given thread to proceed (e.g. consumer is awoken when some other consumer takes item from the queue). Using Lock/Condition API we can implement solution that separates waiting consumers and producers, and hence reduce redundant wakeups and checking:

    Lock lock = new ReentrantLock();
    Condition hasPlace = lock.newCondition();
    Condition hasItems = lock.newCondition();
    




    • 生产者:

      • producer:

        lock.lock();
        try {
            while (queue.isFull()) {
                hasPlace.await();
            }
            queue.put(sth);
            hasItems.signal();
        } finally {
            lock.unlock();
        }
        


      • 消费者:

      • consumer:

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


      • 这样,消费者等待生产者生成一些项目(hasItems条件),并从队列中删除一个项目,它通知生产者有一个空槽(hasPlace条件)。这两个条件都与相同的关键部分(Lock)相关联,因此我们保持通常的排除和释放锁定等待保证,同时获得分离等待队列的能力。

        This way, consumer waits for producers to produce some item (hasItems condition), and upon removing an item from the queue it notifies producers that there is an empty slot (hasPlace condition). Both conditions are associated with the same critical section (Lock), so we keep the usual exclusion and release-lock-while-waiting guarantees, while gaining the ability to separate waiting queues.

        这篇关于条件是否为每个对象提供多个等待集?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆