Java 有锁的条件

Java Conditions with Locks

Java 来自这里的文档 https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Condition.html

我正在尝试理解条件概念。在下面的代码中,put 和 take 都等待同一个锁。文档说在调用任何 condition.await() 之前我们需要获取相应的锁 (here line 2 : final Lock lock = new ReentrantLock();).

我的问题是,假设缓冲区已满。在这种情况下,如果我们尝试插入一个对象,线程将被阻塞直到 count == items.length 但这里的锁仍然保留在试图插入的线程中。我们如何调用方法 take() 来减少计数,因为 take() 需要获取同一锁的持有权。在我看来,这将是死锁,因为无法调用 take(),同样,如果项目为空,我们将无法调用 put(),因为现在锁已经被 take() 使用了。

如有遗漏anything.Thanks请提前帮我理解

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

如果您查看 api 文档中的 Condition#await (https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Condition.html),它说:

The lock associated with this Condition is atomically released and the current thread becomes disabled for thread scheduling purposes and lies dormant until one of four things happens:

既然释放了锁,那么put获取锁就没有问题了