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
Post a Comment