Search code examples
javamultithreadingsynchronizedvisible

can synchronized guarantee variables outside synchronous code block visible between threads?


I have a question about visibility between varaibles in threads (see below), while loop cant stop after I comment synchronized (this){}, but uncomment it, while loop can stop normally, which prove synchronized(this){} can make shared varabiles visible between threads. I know JMM's happens before principle is used to guarantee shared variables visible each other, but I dont know the above code satisfy which principle of happens before? or can synchronized guarantee variables outside synchronous code block visible between threads?

@Slf4j(topic = "threadVisible")
public class ThreadVisible {

int i = 0;

public void go() {
    new Thread(()-> {
        while (true) {
            synchronized (this){}
            if (i != 0) break;
        }
    }).start();
}

public static void main(String[] args) throws InterruptedException {
    ThreadVisible t = new ThreadVisible();
    t.go();
    Thread.sleep(3000);
    t.i = 10;  //
    log.info("end");
}

}


Solution

  • There is no happens before in your code between t.i = 10 and if (i != 0), even with the synchronized statement. The reason is that to create a hb relationship, you need to synchronize the assignment t.i = 10 too.

    The machine (JVM + OS + CPU) on which you run this probably does more than required when calling synchronized and effectively synchronizes everything. On a different machine you could experience an infinite loop.

    Actually you could replace synchronized (this){} by System.out.println("OK") and you would probably get the same behaviour, just because println is synchronized.

    Also empty synchronized statements are rarely what you need, although it makes no difference in your case because of the while loop.