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