You're not misunderstanding ReentrantLock
, you're misunderstanding Condition
. A Condition
is bound to a lock and Condition.await()
will effectively unlock, check and wait, and then relock the lock. See Condition.await()
.
In a()
, between lock()
and the call to await()
, and between the return of await()
and unlock()
, your lock is behaving as you expect. Inside the call to await()
, the Condition
is managing it.
This is part of the general concept of a "condition variable"; it's why any thread library you find associates a lock of some sort with a condition (e.g. in POSIX C, pthread_cond_wait
requires both a condition variable and a mutex).
Check out the Wikipedia article on condition variables, it explains this behavior and the reasons for it in detail.