Condition give the effect of having multiple wait-sets per object?

泪湿孤枕 提交于 2019-12-30 07:39:33

问题


I am reading about Condition in 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.

Can somebody explain me this?

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


回答1:


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();
    }
    

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();
    }
    

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.




回答2:


For a bounded DataStructure for example, you can have the Conditions "notEmpty" and "notFull" and wait for them. Just one example. Have a look at the example here.




回答3:


Previously before the Explicit Locks we used Object wait() and notify() methods for making threads to wait until some event occurred and then triggering them using notify() and the mutex of that Object must be with the thread calling these methods.

So there was only one wait-set per lock object. Wait set is the set where the threads that call wait() on the object are stored (not literraly).

But with the Explicit Lock framework using a single lock you can create multiple wait-sets for different conditions that are related to the same lock. As the example in Javadoc also explain the same fact.

Multiple Conditions == Multiple Wait sets

 final Lock lock = new ReentrantLock(); //Single Lock
 final Condition notFull  = lock.newCondition(); //Multiple conditions
 final Condition notEmpty = lock.newCondition();

So as in the case of Buffer example from JavaDoc consumer threads will wait on the condition for the Buffer to be NOT EMPTY and the producer threads will wait on the condition NOT FULL.



来源:https://stackoverflow.com/questions/18490636/condition-give-the-effect-of-having-multiple-wait-sets-per-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!