locking - Java Condition fail to re-aquire the lock(a ReentrantLock) associated with it after await() returns -
import java.util.linkedlist; import java.util.concurrent.locks.condition; import java.util.concurrent.locks.reentrantlock; class foo { private reentrantlock _lock; private condition _cond; private thread _thr; private linkedlist<string> _msgqueue; public foo() { _lock = new reentrantlock(); _cond = _lock.newcondition(); _msgqueue = new linkedlist<string>(); startthread(); } public void putmsg(string msg) throws exception { _lock.lock(); _msgqueue.addlast(msg); _cond.signal(); system.out.println(thread.currentthread().getid() + ": signal write thread."); _lock.unlock(); system.out.println(thread.currentthread().getid() + ": unlocked."); } private void startthread() { _thr = new thread() { public void run() { _lock.lock(); while(true) { try { while (!_msgqueue.isempty()) { string msg = _msgqueue.getfirst(); system.out.println(msg); _msgqueue.removefirst(); } system.out.println(thread.currentthread().getid() + ": getholdcount:" + _lock.getholdcount()); system.out.println((thread.currentthread().getid() + ": islocked:" + _lock.islocked())); system.out.println(thread.currentthread().getid() + ": isheldbycurrentthread:" + _lock.isheldbycurrentthread()); system.out.println(thread.currentthread().getid() + ": awaiting..."); _cond.await(); system.out.println(thread.currentthread().getid() + ": write thread awaken"); } catch (exception e) { e.printstacktrace(); break; } { try { _lock.unlock(); } catch (exception e) { } } } system.out.println("write thread exit."); } }; _thr.start(); } } public class locktest { public static void main(string[] args) throws exception { foo foo = new foo(); foo.putmsg("msg 1"); foo.putmsg("msg 2"); thread.sleep(1000); foo.putmsg("msg 3"); } }
code output after 1 running: 1: signal write thread. 1: unlocked. 1: signal write thread. 1: unlocked. msg 1 msg 2 8: getholdcount:1 8: islocked:true 8: isheldbycurrentthread:true 8: awaiting... 1: signal write thread. 1: unlocked. 8: write thread awaken msg 3 8: getholdcount:0 8: islocked:false 8: isheldbycurrentthread:false 8: awaiting... write thread exit. java.lang.illegalmonitorstateexception @ java.util.concurrent.locks.reentrantlock$sync.tryrelease(unknown source) @ java.util.concurrent.locks.abstractqueuedsynchronizer.release(unknown source) @ java.util.concurrent.locks.abstractqueuedsynchronizer.fullyrelease(unknown source) @ java.util.concurrent.locks.abstractqueuedsynchronizer$conditionobject.await(unknown source) @ foo$1.run(locktest.java:44)
the question is: according http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/condition.html#await(), when thread returns guaranteed hold lock. output, see after await() returns, not re-aquire lock. bug or mistakes made?
according http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/condition.html#await(), when thread returns guaranteed hold lock.
true, says thread must hold lock before calling method:
the current thread assumed hold lock associated condition when method called. implementation determine if case , if not, how respond. typically, exception thrown (such illegalmonitorstateexception) , implementation must document fact.
this works same way "normal" monitor (object#wait): have hold lock when start waiting (with synchronized block in case of object#wait, lock#lock here). lock released , wait. when wait over, hold lock again.
Comments
Post a Comment