0

I'm so confused about this code :

public class SynchronizedTest implements Runnable {

private int b = 100;

public synchronized void test01() throws InterruptedException {
    b = 1000;
    Thread.sleep(5000);
}

public synchronized void test02() throws InterruptedException {
    b = 2000;
    Thread.sleep(2500);
  //System.out.println("test02 end !");
}

@Override
public void run() {
    try {
        test01();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

public static void main(String[] args) throws InterruptedException {
    SynchronizedTest test = new SynchronizedTest();
    Thread thread01 = new Thread(test);
    thread01.start();
    test.test02();
    System.out.println(test.b);
}

}

If I don't add this code System.out.println("test02 end !"); in above code.

The operation result will be print 1000 , but if put the code there the operation result will change to "test02 end !" and 2000;

I don't know why, how to explaint it ?

bhansa
  • 7,282
  • 3
  • 30
  • 55
J.Joe
  • 81
  • 1
  • 7
  • System.out.printline() is not threadsafe https://stackoverflow.com/questions/9459657/synchronization-and-system-out-println – User Sep 29 '17 at 07:56
  • Is still not threadsafe now ? the source code add sychnroized now public void println(int x) { synchronized (this) { print(x); newLine(); } } – J.Joe Sep 29 '17 at 08:04
  • I think the problem is run order , Athought Sout is not threadsafe , there is no affects for the code . – J.Joe Sep 29 '17 at 08:07
  • Your test.b is not thread-safe :o – Nam Tran Sep 29 '17 at 08:08
  • how about volatile ? that will make the test.b threadsafe ? – J.Joe Sep 29 '17 at 08:12
  • When `System.out.println()` is reached to call `test.b`, do you know the method `test01` is started or not? If it is started and set `b=1000`, your program updates `test.b` value right before it is called to print or not? your main thread is now free to access test.b. For your title question, it is 'Yes', `System.out.println()` affects your program running order. – Nam Tran Sep 29 '17 at 08:31
  • i think the problem is not threadsafe . maybe some things else .. thanks ~ – J.Joe Sep 29 '17 at 08:53

1 Answers1

0

This is definitely related to the way the compiler is scheduling the instructions. The value of b is being changed, however the compiler has scheduled the print instruction before calling the test02 function.

SynchronizedTest test = new SynchronizedTest();
Thread thread01 = new Thread(test);
thread01.start();
System.out.println(test.b);
System.out.println(test.b);
test.test02();
System.out.println(test.b);

I tried the above order, and the output was

100
1000
2000

This also supports my argument. This is not happening if you uncomment the print statement as the compiler now deduces that it has to print the text inside the test02 function and hence does not change the order of the execution.

However I am unsure as to why the compiler is changing the order in the first case.

  • My code operation result not same with your's ... print 100,100,2000.. i think there no way to print 1000 , bacause when test02 run , the SynchronizedTest object is locked , only test02 end there will be test01 .Total time consuming is 7.5 seconds – J.Joe Sep 29 '17 at 07:46
  • I think that completely depends upon the compiler. I did get 1000 printed. This is something which we cannot completely comprehend without the knowledge of how the compiler was built. – Gurpreet Singh Sep 29 '17 at 07:50