Below is the code. The output is 1000, b=1000. I don't understand why m2() runs first every time.
public class TT implements Runnable{
int b = 100;
public synchronized void m1() throws Exception {
b = 1000;
Thread.sleep(100);
System.out.println("b =" + b);
}
public synchronized void m2() throws Exception {
Thread.sleep(2000);
b = 2000;
}
public void run() {
try {
m1();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
TT tt = new TT();
Thread t = new Thread(tt);
t.start();// m1() starts
tt.m2();// m2() starts
System.out.println(tt.b);
}
}
The real reason1 the synchronized keyword.
The m2() method acquires the lock on the TT instance, and then sleeps. Meanwhile, the thread start takes effect and the run() method attempts to call m1(). But m1() has to wait until the call to m2() completes and releases the lock.
Now if the new thread is started and manages to call m1() before the existing thread calls m2(), then you will see the events in the other order. This is theoretically possible ... but unlikely on typical Java platforms. (Typically, the parent thread is not descheduled when it starts a child thread.)
What happens after m2() returns will determine the output you see. Since you accessing tt.b directly (without any synchronization), the result is not predictable from a theoretical perspective.
Basically, this just illustrates that sleep is the wrong way to do thread scheduling. If you want one event on one thread to happen before another event on a different, the threads need to coordinate explicitly. Relying on sleep and serendipitous timing effects (like thread.start() typically taking a long time) will give you unreliable behavior.
1 - Obviously, it is a combination of things. But the real reason with the sleep hackery is not working as expected is the synchronized keywords.
If you want tt.m2() to run after t thread finished it's job. Add t.join() after t.start(). This makes the main Thread to run after t has finished its job.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With