In the below code about the synchronisation between threads, according to the output generated why is the control being transferred to the execution of the new thread despite the lock being acquired for the same object "dt" in the main method ?
public class DemoThread extends Thread {
public DemoThread() {
}
public void run() {
int i=0;
synchronized(this) {
while(++i<=5) {
sum=i;
try{
sleep(1000);
System.out.println("Woke up from sleep");
if(i>=2) this.notify();
}catch(InterruptedException ie) {
ie.printStackTrace();
System.exit(1);
}
}
}
}
private static int sum;
public static void main(String... args) {
DemoThread dt = new DemoThread();
dt.start();
synchronized(dt) {
try{
System.out.println("main here");
dt.wait();
System.out.println("main here again");
System.out.println("sum = " + sum);
}catch(InterruptedException ie){
ie.printStackTrace();
System.exit(1);
}
}
}
}
Output :
main here
Woke up from sleep
Woke up from sleep
Woke up from sleep
Woke up from sleep
Woke up from sleep
main here again
sum = 5
EDIT: I think I was able to find one of the possible flow of the code to explain the output:
1.Main thread enters in the Sync block in the main method.
2.call to the wait is made. Lock released on the dt object
3.New thread enters the while loop as it has the lock on the object dt
4.Thread.Sleep is executed and it doesn't release the lock
5.notify call is made but doesnot wakr the main thread(?)
6.New and the main thread finish the execution
Please correct me if I am wrong
You are close :
Until the step 4, it is correct.
Here is what it happens at the step 5 :
notify()
is invoked and themain()
thread is so notified.But it will not have a chance to run again right now.
Why ? Because the
DemoThread
thread doesn't release the lock.The
notify()
method is indeed executed in a loop inside asynchronized
statement.And according to
Object.notify()
javadoc :So the
main()
thread could run only as therun()
methodDemoThread
is terminated.To let the
main()
thread to run again, you could reverse in theDemonThread
run()
method, thesynchronized
statement and thewhile
statement.You should also make this thread sleep a little bit to let the
main()
thread to run again.Now as
i >= 2
, as previously, other threads are notified but as the thread leaves the lock as it loops on thewhile
and then sleep 100 ms, the main() thread can run again.Here is the output :
The synchronized keyword isn't used to control the execution of a thread, it's used to ensure that only one thread can enter a block of code at any one time. Typically whole methods can be synchronized or code between {}.
You can also synchronize an object that will be shared between two or more threads, typically some data structure that will be updated by the threads and you need to ensure that the state is consistent and not partially updated.
In your example there is no contention on the synchronize, if you extedt the sample to introduce some object and multiple threads trying to write and read from this object you will get a better understanding.