Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Item 66: Synchronize access to shared mutable data [duplicate]

Tags:

java

I am now reading 《effective Java》 and meeting a confusion.

For code 1 (java8) :

public class StopThreadTest {

    private static Boolean stopRequest = false;

    public static void main(String[] args) throws InterruptedException {
        new Thread(()->{
            int i = 0;
            while (!stopRequest) {
                i++;
                //System.out.println("i: " + i);
            }
        }).start();

        TimeUnit.SECONDS.sleep(1);
        stopRequest = true;
    }
}

the program never terminates.

For code 2(java8):

public class StopThreadTest {

    private static Boolean stopRequest = false;

    public static void main(String[] args) throws InterruptedException {
        new Thread(()->{
            int i = 0;
            while (!stopRequest) {
                i++;
                System.out.println("i: " + i);
            }
        }).start();

        TimeUnit.SECONDS.sleep(1);
        stopRequest = true;
    }
}

Just adding System.out.println(), the program run about 1 second.

Can anybody tell me why?

like image 970
Dustin Avatar asked Sep 14 '25 23:09

Dustin


1 Answers

System.out.println() is synchronized, removing the visibility issues with the original code. Without it, the thread can use its cached value of stopRequest and keep on running, but when println() is involved, caches are flushed and the modified value can be seen.

From PrintStream.println(String x)

synchronized (this) {
    print(x);
    newLine();
}

Note that this is a side-effect only. It explains the difference in behaviour, but it's not something you can rely on for correct functionality of code.

like image 128
Kayaman Avatar answered Sep 17 '25 14:09

Kayaman