1

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");
}

}

xiaodao
  • 13
  • 4

1 Answers1

0

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.

assylias
  • 321,522
  • 82
  • 660
  • 783
  • thank for your reply. actually, I cant understand why `System.out.println()` can make `while loop` exit, I saw many blogs, some think the reason is synchronous code block in system.out.println, but I cant find out `hp`, so I write this test code. according to you, JVM does not guarantee visibility of variable `t.i` between threads, just because of platform? – xiaodao Aug 03 '22 at 12:32
  • No, the Java memory model does not guarantee visibility in your example, but on typical hotspot JVM / x86 infrastructure, the effect of synchronized will be enough to make the write visible. In other words, the code is buggy because it relies on behaviour that is not documented in the Java specifications. – assylias Aug 03 '22 at 12:36