Java : Does wait() release lock from synchronized block

I was under the impression that wait() releases all locks but I found this post which says

"Invoking wait inside a synchronized method is a simple way to acquire the intrinsic lock"

Please clarify I'm a bit confused.

http://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html


"Invoking wait inside a synchronized method is a simple way to acquire the intrinsic lock"

This sentence is false, it is an error in documentation.

Thread acquires the intrinsic lock when it enters a synchronized method. Thread inside the synchronized method is set as the owner of the lock and is in RUNNABLE state. Any thread that attempts to enter the locked method becomes BLOCKED.

When thread calls wait it releases the current object lock (it keeps all locks from other objects) and than goes to WAITING state.

When some other thread calls notify or notifyAll on that same object the first thread changes state from WAITING to BLOCKED, Notified thread does NOT automatically reacquire the lock or become RUNNABLE, in fact it must fight for the lock with all other blocked threads.

WAITING and BLOCKED states both prevent thread from running, but they are very different.

WAITING threads must be explicitly transformed to BLOCKED threads by a notify from some other thread.

WAITING never goes directly to RUNNABLE.

When RUNNABLE thread releases the lock (by leaving monitor or by waiting) one of BLOCKED threads automatically takes its place.

So to summarize, thread acquires the lock when it enters synchronized method or when it reenters the synchronized method after the wait.

public synchronized guardedJoy() {
    // must get lock before entering here
    while(!joy) {
        try {
            wait(); // releases lock here
            // must regain the lock to reentering here
        } catch (InterruptedException e) {}
    }
    System.out.println("Joy and efficiency have been achieved!");
}

I've prepared a small test class (some very dirty code, sorry) to demonstrate that wait actually releases the lock.

public class Test {
    public static void main(String[] args) throws Exception {
        testCuncurrency();
    }

    private static void testCuncurrency() throws InterruptedException {
        Object lock = new Object();
        Thread t1 = new Thread(new WaitTester(lock));
        Thread t2 = new Thread(new WaitTester(lock));
        t1.start();
        t2.start();
        Thread.sleep(15 * 1000);
        synchronized (lock) {
            System.out.println("Time: " + new Date().toString()+ ";" + "Notifying all");
            lock.notifyAll();
        }
    }

    private static class WaitTester implements Runnable {
        private Object lock;
        public WaitTester(Object lock) {
            this.lock = lock;
        }

        @Override
        public void run() {
            try {
                synchronized (lock) {
                    System.out.println(getTimeAndThreadName() + ":only one thread can be in synchronized block");
                    Thread.sleep(5 * 1000);

                    System.out.println(getTimeAndThreadName() + ":thread goes into waiting state and releases the lock");
                    lock.wait();

                    System.out.println(getTimeAndThreadName() + ":thread is awake and have reacquired the lock");

                    System.out.println(getTimeAndThreadName() + ":syncronized block have finished");
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    private static String getTimeAndThreadName() {
        return "Time: " + new Date().toString() + ";" + Thread.currentThread().getName();
    }
}

Running this class on my machine returns next result:

Time: Tue Mar 29 09:16:37 EEST 2016;Thread-0:only one thread can be in synchronized block
Time: Tue Mar 29 09:16:42 EEST 2016;Thread-0:thread goes into waiting state and releases the lock
Time: Tue Mar 29 09:16:42 EEST 2016;Thread-1:only one thread can be in synchronized block
Time: Tue Mar 29 09:16:47 EEST 2016;Thread-1:thread goes into waiting state and releases the lock
Time: Tue Mar 29 09:16:52 EEST 2016;Notifying all
Time: Tue Mar 29 09:16:52 EEST 2016;Thread-1:thread is awake and have reacquired the lock
Time: Tue Mar 29 09:16:57 EEST 2016;Thread-1:syncronized block have finished
Time: Tue Mar 29 09:16:57 EEST 2016;Thread-0:thread is awake and have reacquired the lock
Time: Tue Mar 29 09:17:02 EEST 2016;Thread-0:syncronized block have finished