Reputation: 369
it is an example about wait()
and notify()
in Java Concurrency. My theory knowledge about it doesn't explain me about this code and I cannot explain why this gives me a misunderstood result.
So, This is code to get an idea:
public class ExampleOne {
public static void main(String[] args) {
Test b = new Test();
b.start();
synchronized(b){
try{
b.wait();
} catch(InterruptedException ex){
ex.printStackTrace();
}
System.out.println(b.total);
}
}
}
class Test extends Thread {
int total;
@Override
public void run(){
synchronized(this){
for(int i =0;i<50;i++){
total+=i;
System.out.println("I am here");
}
notify();
}
}
}
The result is : 4950
So, how to understand this process (how total
can be 4950)?
I understand that If I call wait()
it stops the object's thread which called this method and woken up it then another thread calls notify()
. Also, synchronized()
block restricts threads and accept only one thread in one time.
So when thread calls notify(), it becomes non-active until other thread calls wait()?
How wait() and notify() play it's role in this code? Also synchronized()
block?
So, how many threads are created in this code?
I am confused about this. Help me to figure it out.
Upvotes: 0
Views: 87
Reputation: 691993
To complement Gray's excellent answer, here's what happens:
main thread:
---------------------------------------------------->
| | |
start Test thread waits until notified wakes up and prints the result
Test thread:
------------------------>
| |
starts running notifies main thread
computes the sum
Also note that it's generally considered bad practice to call wait()
and notify()
on a Thread instance. A shared object, acting as a lock, should be used instead. notifyAll()
should be preferred generally, or even better, a higher-level abstraction like a CountDownLatch should used.
Upvotes: 2
Reputation: 116908
If I call wait() it stops the object's thread which called this method and woken up it then another thread calls notify()
Right. notify()
or notifyAll()
on the same object instance will awaken the thread.
So when thread calls notify(), it becomes non-active until other thread calls wait()?
No. Notify just signals a thread that is waiting on the same object. The thread that calls notify()
continues running and does not release the synchronized
lock that it is holding.
How wait() and notify() play it's role in this code?
Without wait/notify. the main thread would not wait for the calculation to finish so would probably print 0.
Also synchronized() block?
When you use wait()
or notify()
you need to be in a synchronized
block. It is the monitor associated with the object instance that you are synchronized
on that is being waited on and being notified. Also, the synchronized
block ensures memory synchronization so the main threads sees the changes to the notify
field. Each thread has a memory cache and there needs to be mechanisms in place for threads to publish their changes and see changes to fields made by other threads.
So, how many threads are created in this code?
1 thread is created by your code and the main thread is created automagically by the JVM.
It is important to realize that there is a race condition in this code. It is possible for the new thread to start up, spin through the loop, call notify and exit before the main thread actually calls wait
. This is unlikely because starting a thread takes some time but it could happen. In that case, the main thread would be stuck in wait
forever because there is no one there to notify it.
Couple other comments:
this.notify()
. It's always good to reiterate what is being notified
.private final
lock object as opposed to a Thread
object.implements Runnable
as opposed to extending thread. Then you would do new Thread(new TestRunnable()); ...
.Upvotes: 5