Two threads executing synchronized block simultaneously
Below is the code where a Thread enters a synchronized block, waits for 5seconds and then exits. I have started two Thread instances simultaneously.
The expectation was one of the threads will own the lock on the synchronized object & the other will wait. After 5 seconds, when the lock owner exits, the waiting thread will execute.
But, in actual, both the threads are executing the synchronized block simultaneously and also exiting at the same time.
Expected Output:
Thread-X <timeX> received the lock.
Thread-X <timeX+5s> exiting...
Thread-Y <timeY> received the lock.
Thread-Y <timeY+5s> exiting...
Actual Output:
Thread-X <time> received the lock.
Thread-Y <time> received the lock.
Thread-X <time+5s> exiting...
Thread-Y <time+5s> exiting...
Any explanation of the above behavior will be really helpful. Am I missing something here?
import java.text.SimpleDateFormat;
import java.util.Date;
public class Test2 {
public static void main(String[] args) {
MyRunnable m = new MyRunnable();
Thread t = new Thread(m);
Thread t1 = new Thread(m);
t.start();
t1.start();
}
}
class MyRunnable implements Runnable {
@Override
public void run() {
synchronized (this) {
try {
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
Date date = new Date(System.currentTimeMillis());
System.out.println(Thread.currentThread().getName() + " " + formatter.format(date) + " received the lock.");
wait(5000);
date = new Date(System.currentTimeMillis());
System.out.println(Thread.currentThread().getName() + " " + formatter.format(date) + " exiting...");
} catch(InterruptedException ie) {}
}
}
}
The answer lies in java.lang.Object.wait(long) whose documentation says:
[...] This method causes the current thread (call it T) to place itself in the wait set for this object and then to relinquish any and all synchronization claims on this object. [...]
Use
Thread.sleep(5000);
JavaDocs for Thread.sleep:
Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds, subject to the precision and accuracy of system timers and schedulers. The thread does not lose ownership of any monitors.
The following quote from the Oracle Tutorials explains the situation:
When wait is invoked, the thread releases the lock and suspends
execution.
Also, only one thread can execute a synchronized block guarded by the same object! Calling wait in your example releases the lock, thus allowing another thread to acquire the lock.
The expectation was one of the threads will own the lock on the synchronized object & the other will wait. After 5 seconds, when the lock owner exits, the waiting thread will execute.
But, in actual, both the threads are executing the synchronized block simultaneously and also exiting at the same time.
Expected Output:
Thread-X <timeX> received the lock.
Thread-X <timeX+5s> exiting...
Thread-Y <timeY> received the lock.
Thread-Y <timeY+5s> exiting...
Actual Output:
Thread-X <time> received the lock.
Thread-Y <time> received the lock.
Thread-X <time+5s> exiting...
Thread-Y <time+5s> exiting...
Any explanation of the above behavior will be really helpful. Am I missing something here?
import java.text.SimpleDateFormat;
import java.util.Date;
public class Test2 {
public static void main(String[] args) {
MyRunnable m = new MyRunnable();
Thread t = new Thread(m);
Thread t1 = new Thread(m);
t.start();
t1.start();
}
}
class MyRunnable implements Runnable {
@Override
public void run() {
synchronized (this) {
try {
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
Date date = new Date(System.currentTimeMillis());
System.out.println(Thread.currentThread().getName() + " " + formatter.format(date) + " received the lock.");
wait(5000);
date = new Date(System.currentTimeMillis());
System.out.println(Thread.currentThread().getName() + " " + formatter.format(date) + " exiting...");
} catch(InterruptedException ie) {}
}
}
}
The answer lies in java.lang.Object.wait(long) whose documentation says:
[...] This method causes the current thread (call it T) to place itself in the wait set for this object and then to relinquish any and all synchronization claims on this object. [...]
Use
Thread.sleep(5000);
JavaDocs for Thread.sleep:
Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds, subject to the precision and accuracy of system timers and schedulers. The thread does not lose ownership of any monitors.
The following quote from the Oracle Tutorials explains the situation:
When wait is invoked, the thread releases the lock and suspends
execution.
Also, only one thread can execute a synchronized block guarded by the same object! Calling wait in your example releases the lock, thus allowing another thread to acquire the lock.
Comments
Post a Comment