-1

Why is wait() inside of a synchronized block? I mean, only one thread will enter the synchronized block, so how can the other thread execute the wait() instruction?

As As
  • 2,049
  • 4
  • 17
  • 33
  • 2
    Which `synchronized` block are you talking about? Your question is really unclear (and broad too)... – BackSlash Aug 29 '14 at 12:49
  • None of the answers, either here or in the duplicate, mention the quintessential reason: `notifyAll` would be a total mess without the requirement to re-acquire the lock before continuing. – Marko Topolnik Aug 29 '14 at 13:22
  • It's because before you can wait for something, you have to make sure that something hasn't already happened. And you have to make sure it doesn't happen right as you go to wait. So you must hold a lock to wait for something -- the lock that protects the thing that you're waiting for's state change. – David Schwartz Mar 30 '16 at 09:35

2 Answers2

2
  1. Synchronized keyword is used for exclusive accessing.
  2. To make a method synchronized, simply add the synchronized keyword to its declaration. Then no two invocations of synchronized methods on the same object can interleave with each other.
  3. Synchronized statements must specify the object that provides the intrinsic lock. When synchronized(this) is used, you have to avoid to synchronizing invocations of other objects' methods.
  4. wait() tells the calling thread to give up the monitor and go to sleep until some other thread enters the same monitor and calls notify( ).
  5. notify() wakes up the first thread that called wait() on the same object.

Example:

public class ThreadA {
    public static void main(String[] args){
        ThreadB b = new ThreadB();
        b.start();

        synchronized(b){
            try{
                System.out.println("Waiting for b to complete...");
                b.wait();
            }catch(InterruptedException e){
                e.printStackTrace();
            }

            System.out.println("Total is: " + b.total);
        }
    }
}

class ThreadB extends Thread{
    int total;
    @Override
    public void run(){
        synchronized(this){
            for(int i=0; i<100 ; i++){
                total += i;
            }
            notify();
        }
    }
}

Got it from: http://www.programcreek.com/2009/02/notify-and-wait-example/

Bruno Franco
  • 2,028
  • 11
  • 20
  • Why is `synchronized(this)` is being called in `ThreadB`? Isn't only the thread itself calls run, and no other threads? – Artemkller545 Aug 29 '14 at 12:56
  • When i tried running without this synchronized block, i got a java.lang.IllegalMonitorStateException, it is interesting. When threadA synchronized over b, it needs guarantee that notify() is synchronized too, or other instance could call notify. – Bruno Franco Aug 29 '14 at 13:17
0
Why is wait() inside of a synchronized block?

Because the thread needs to have the monitor of the object you're calling wait() on, in the case of a synchronized method, the this object.

I mean, only one thread will enter the synchronized block, so how can the other 
thread execute the wait() instruction?

It can't, only the thread inside the synchronized block can perform wait(), allowing other threads to enter the synchronized block.

Kayaman
  • 72,141
  • 5
  • 83
  • 121
  • "why is [foo.]wait [required to be] inside [synchronized(foo)]?" You basically said, "Because it is requried." A better answer would say _why_. A complete answer is too big for this space, but in a nutshell; the caller of `foo.wait()` should be waiting for some explicit, testable condition and, in order to avoid "lost notifications," every block of code that can test or change the condition (including the waiter) should be synchronized on the same lock. Java can't enforce that _every_ block of code is synchronized, but it does so for the block that wait()s and the block that notify()s. – Solomon Slow Aug 29 '14 at 13:19