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");
}
}
CodePudding user response:
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.