How do java.util.concurrent.locks.Condition work?

一曲冷凌霜 提交于 2020-05-14 18:17:04

问题


Reading the Java 8 documentation about the java.util.concurrent.locks.Condition interface, the following example is given:

class BoundedBuffer {
   final Lock lock = new ReentrantLock();
   final Condition notFull  = lock.newCondition(); 
   final Condition notEmpty = lock.newCondition(); 

   final Object[] items = new Object[100];
   int putptr, takeptr, count;

   public void put(Object x) throws InterruptedException {
     lock.lock();
     try {
       while (count == items.length)
         notFull.await();
       items[putptr] = x;
       if (++putptr == items.length) putptr = 0;
       ++count;
       notEmpty.signal();
     } finally {
       lock.unlock();
     }
   }

   public Object take() throws InterruptedException {
     lock.lock();
     try {
       while (count == 0)
         notEmpty.await();
       Object x = items[takeptr];
       if (++takeptr == items.length) takeptr = 0;
       --count;
       notFull.signal();
       return x;
     } finally {
       lock.unlock();
     }
   }
 }

So my main question is: How does a condition work?

  1. Does it release the lock when it starts waiting? (notFull.await() for example)?
  2. Can different threads acquire the same lock and move until it signal() a condition, awaking other threads?
  3. I thought this example would result in a deadlock because if a thread is waiting for the buffer to not be empty and it hasn't release the lock yet, how can another thread acquire the lock, empty the buffer, signal() the condition is now met, and release the lock if the lock hasn't been release by the thread waiting for the buffer to be not full?

These are beginners questions. Please help me out.

Thank you.


回答1:


  1. Yes that is right, as soon as it awaits for a condition, it releases the lock. await/signal/signalAll has actually the same behavior as wait/notify/notifyAll
  2. No the ReentrantLock is an exclusive lock so only one thread can acquire the lock.
  3. See #1. When a thread call signal or signalAll, it releases respectively one thread or all threads awaiting for the corresponding Condition such that the thread or those threads will be eligible to acquire the lock again. But for now the lock is still owned by the thread that called signal or signalAll until it releases explicitly the lock by calling lock.unlock. Then the thread(s) that has/have been released will be able to try to acquire the lock again, the thread that could acquire the lock will be able to check the condition again (by condition this time I mean count == items.length or count == 0 in this example), if it is ok it will proceed otherwise it will await again and release the lock to make it available to another thread.


来源:https://stackoverflow.com/questions/36435753/how-do-java-util-concurrent-locks-condition-work

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