2

I'm quite confused regarding how wait() method in threads work. Suppose I write:

public class test3 {
    public static void main(String args[]){
        Thread A = new Thread();
synchronized(this){
            A.wait();
}
    }
}

Now here method wait() will be called by which thread - Main thread or Thread A, in other sense, which thread will leave the monitor and temporarily go to sleep.

TheLostMind
  • 35,966
  • 12
  • 68
  • 104
Shivam Aggarwal
  • 734
  • 2
  • 9
  • 23
  • This is just a sample code. Suppose I've kept the wait() method inside a synchronized block then who did call wait(), main thread or thread A – Shivam Aggarwal Dec 13 '15 at 10:00
  • 2
    You should never call wait() on a Thread object, as documented. Most of your confusion probably comes from that bad practice. wait() should be called on a "regular" object shared by several threads. – JB Nizet Dec 13 '15 at 10:10
  • 1
    @JBNizet - Right. And another common confusion is that - *creating an instance of Thread is not the same as executing a Thread* :) – TheLostMind Dec 13 '15 at 10:13
  • @JBNizet "() should be called on a "regular" object shared by several threads " what does this statement mean. Can you please elaborate :). – Shivam Aggarwal Dec 13 '15 at 10:18
  • @VinodMadyalkar why is it so. We use wait() to prevent a thread to move any further unless notify() is called. To me it seems meaningless to call wait() on objects other than threads . – Shivam Aggarwal Dec 13 '15 at 10:20
  • 1
    @Brut3Forc3 - OK. You are calling `wait()` and `notify()` on an instance of `Thread` . So, here `A` will act as a lock and NOT as a running thread. The main thread will try to wait on `A` . You can use *any other object* instead of an instance of Thread here. got it? – TheLostMind Dec 13 '15 at 10:25
  • 2
    @Brut3Forc3 first, your code sample executes a single thread: the main thread. Creating anobject of type Thread doesn't start a separate thread of execution. The typical use-case of wait() and notify() is the producer-consumer pattern: you create a list. You start a producer thread that adds elements to that list. You start a consumer thread that gets and removes elements from that list. The consumer must block while the list is empty. The producer must block when the list size reaches, for example, 100 elements. In such an example, the list would be the regular object shared by two threads – JB Nizet Dec 13 '15 at 10:27
  • 2
    Note though that wait() and notify() are very low-level methods, that are hard to use well. You should prefer a BlockingQueue to implement such a pattern. The BlockingQueue will do the hard job for you. It's much too soon for you to use those complex methods. Start by understanding what a thread is, how you start one, and why you need to synchronize accesses to shared state. And before that, learn what a static method is, and why you may not use `this` in a static method. Those steps are important ones. Learning takes time. – JB Nizet Dec 13 '15 at 10:30
  • Thanks for those explanations guys :) . – Shivam Aggarwal Dec 13 '15 at 11:53

1 Answers1

3

The main thread will wait on the instance of A. i.e, the thread A will serve as the lock and main thread will wait on it for another thread to call notify() .

Note - calling wait() / notify() without acquiring lock on the instance will lead to IllegalMonitorStateException.

wait() and notify() are methods defined in the Object class. Threads call wait() and notify() on instances (AKA known as locks AKA monitors). So, when you use synchronized keyword, you acquire a lock (also known as entering the monitor) on the object you have synchronized on. Next, when you call wait(), the thread which has acquire the lock will wait for another thread to call notify() on the same instance (same lock).

TheLostMind
  • 35,966
  • 12
  • 68
  • 104
  • Sir could you please elaborate I'm really confused with locks and thread wait() method – Shivam Aggarwal Dec 13 '15 at 10:04
  • So, basically a thread calling wait() means that it is stopped from doing actions any further on that data item unless a notify is called. Now can I call a notify from a different thread to again permit my waited thread to do further actions – Shivam Aggarwal Dec 13 '15 at 10:13
  • 2
    Yes, you can, that's the whole idea. – Alexander Kulyakhtin Dec 13 '15 at 10:14
  • 1
    @Brut3Forc3 - *So, basically a thread calling wait() means that it is stopped from doing actions any further on that data item unless a notify is called.* - Yes. `notify()`, `notifyAll()` or the thread could be explicitly interrupted. It is important that the other thread calls `notify()` on the same lock / instance – TheLostMind Dec 13 '15 at 10:15
  • So here "current thread" is my main thread. If it is so then how do I call a notify for my main thread ? How do I get the "same lock/instance" for my main thread – Shivam Aggarwal Dec 13 '15 at 10:17
  • 1
    @Brut3Forc3 - Like I pointed out earlier, you have not acquired a lock (no *synchronization*), your code will fail with `IllegalMonitorStateException`. You should look up a simple *producer0consumer* example on how to use `wait()` and `notify()` – TheLostMind Dec 13 '15 at 10:19
  • Alright then now I've modified my code like this. Will it work now ? – Shivam Aggarwal Dec 13 '15 at 10:27
  • @Brut3Forc3 - It won't :). `this` can't be used inside a `static` method :P – TheLostMind Dec 13 '15 at 10:27
  • @VinodMadyalkar also I would like to ask why do we always use wait() and notify() in synchronized blocks only. I know this is a much asked and answered question and I found one such here http://stackoverflow.com/questions/2536692/a-simple-scenario-using-wait-and-notify-in-java . Please look into Jared's (accepted answer) answer. I've written a comment there regarding the mistake he made in his explanation (atleast what I understood from it). I'd really love to get a explanation on this topic from you :) . – Shivam Aggarwal Dec 13 '15 at 13:33
  • @Brut3Forc3 - See, calling `wait()` and `notify()` on an instance involves acquiring the lock / monitor of that object first. When you do `synchronized(someInstance) {..}`, you acquire a lock on `someInstance`. For methods like - `public synchronized void someMethod() {..}`, you are *implicitly* acquring the lock on the *current instance* AKA `this`. So, only when a thread acquires a lock on an Object, it will be able to `wait()` on it or call `notify()` on it. – TheLostMind Dec 13 '15 at 16:00
  • @VinodMadyalkar wait() will release it. Not notify(). – JB Nizet Dec 13 '15 at 16:07
  • @Brut3Forc3- His answer is right. JB Nizet has already commented on that post. wait() (unlike sleep()) will release the lock thus another thread can take it, do what it wants to do, and call `notify()`. – TheLostMind Dec 13 '15 at 16:15
  • @JBNizet - Ya sorry about that. long day... :P – TheLostMind Dec 13 '15 at 16:15
  • But he says that the condition is checked but before wait is called and another thread is scheduled. This is where I find it ambiguous. – Shivam Aggarwal Dec 13 '15 at 16:20