javamultithreadingblockinglocks

Java Conditions with Locks


Java docs from here https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Condition.html

I am trying to understand the Conditions concept. In the below code, put and take both wait on the same Lock. The doc says that before calling any condition.await() we need to get hold of the corresponding lock (here line 2 : final Lock lock = new ReentrantLock();).

My question is, lets say the buffer is full. In this case if we try to insert an object, the thread will be blocked till count == items.length but the lock here still remains with the thread which is trying to put. How can we call method take() to decrease the count, since take() needs to acquire the hold of the same Lock. It apears to me that this will be deadlock as take() cannot be called, same if the items is empty we won't be able to call put() since now the lock is already with take().

Kindly help me understand if i am missing anything.Thanks in advance.

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

Solution

  • If you look at the api doc for Condition#await ( https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Condition.html) it says:

    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:

    Since the lock is released there is no problem with put acquiring the lock.