I am in doubt with that , in Java language, we need to acquire the lock, before we await some condition to be satisfied.
For example, int java monitor lock:
Well, what are we waiting for? We are waiting for a condition to become true. Another thread will make the condition true, then notify the waiting threads.
Before entering wait, we must check that the condition is false; this check and the wait must be atomic, i.e. under the same lock. Otherwise, if we enter the wait while the condition is already true, we'll likely never wakeup.
Therefore it is necessary that the lock is already acquired before calling wait()
synchronized(lock)
{
if(!condition)
lock.wait();
If wait() automatically and silently acquires lock, a lot of bugs will go undetected.
Upon wakeup from wait(), we must check the condition again -- there's no guarantee that the condition must become true here (for lots of reasons - spurious wakeup; timeout, interruption, multiple waiters, multiple conditions)
synchronized(lock)
{
if(!condition)
lock.wait();
if(!condition) // check again
...
Typically, if the condition is still false, we'll wait again. Therefore the typical pattern is
while(!condition)
lock.wait();
But there are also cases where we don't want to wait again.
Could there ever be legit use cases where naked wait/notify make sense?
synchronized(lock){ lock.wait(); }
Sure; an application can be made up with naked wait/notify, with well defined behavior; argument can be made that this is the desired behavior; and this is the best implementation for that behavior.
However, that is not the typical usage pattern, and there is no reason to account for it in API design.