java - Why ReentrantLock with Conditions can be acquired by two threads in ArrayBlockingQueue -


it might stupid question can't understand why single reentrantlock can taken 2 different threads in class (it's simplified solution of arrayblockingqueue used play threads , locks):

class samplethreadsafequeue {          private reentrantlock lock = new reentrantlock();         private list<integer> list = new arraylist<>();         private condition notempty;         private condition notfull;         private volatile int count;          public samplethreadsafequeue() {             notempty = lock.newcondition();             notfull = lock.newcondition();         }          public int take() {             try {                 lock.lock();                 system.out.println(thread.currentthread().getname() +": acquired lock in take()");                 while (count == 0) {                     notempty.await();                 }                  return extract();             } catch (exception e) {                 e.printstacktrace();                 return 0;             } {                 system.out.println(thread.currentthread().getname() +": released lock take()");                 lock.unlock();             }         }          private int extract() {             int index = count <= 0 ? 0 : count - 1;             integer integer = list.get(index);             list.remove(index);             count--;             list.clear();             notfull.signal();             return integer;         }          public void put(int value) {             try {                 lock.lock();                 system.out.println(thread.currentthread().getname() +": acquired lock in put()");                 while (!list.isempty()) {                     notfull.await();                 }                 thread.sleep(3000); // let's assume takes 3 secs add value                 insert(value);             } catch (exception e) {                 e.printstacktrace();             } {                 system.out.println(thread.currentthread().getname() +": released lock put()");                 lock.unlock();             }         }           private void insert(int value) {             list.add(value);             count = list.size();             notempty.signal();         }     } 

i receive result in console:

pool-1-thread-1: acquired lock in put() pool-1-thread-1: released lock put() pool-1-thread-1: acquired lock in put()    - guy has taken lock pool-1-thread-2: acquired lock in take()   - guy has taken lock well! wtf? pool-1-thread-2: released lock take() value = 0 pool-1-thread-2: acquired lock in take() pool-1-thread-1: released lock put() pool-1-thread-1: acquired lock in put() pool-1-thread-2: released lock take() value = 1 pool-1-thread-1: released lock put() pool-1-thread-1: acquired lock in put() pool-1-thread-2: acquired lock in take() pool-1-thread-2: released lock take() value = 2 ... 

i suspect it's because of conditions use in while cycle logically can't understand why happen. appreciate explanations. thanks!

when call await() on condition obtained lock, thread releases lock , stops until condition notified thread (by means of signal() or signalall()).

so, thread 1 acquires lock, calls await() , switches waiting mode, releasing lock lately acquired thread 2. when thread 2 done, notifies thread 1 (by calling signal()) , releases lock. lock reacquired thread 1, awakes , continues doing work , releases lock.

then repeat in different order.


Comments

Popular posts from this blog

mysql - Dreamhost PyCharm Django Python 3 Launching a Site -

java - Sending SMS with SMSLib and Web Services -

java - How to resolve The method toString() in the type Object is not applicable for the arguments (InputStream) -