问题描述
synchronized是如何实现可见性的,我在线程B加入了一个空的同步代码块后,线程B就能正确读到i的值为1,实现了可见性,如果不加同步代码块线程B就不会停止。可是就算加了一个空的同步代码块,线程A执行i=1后应该也只是在工作内存中执行的,并未刷新到主存,虽然线程B执行同步代码块加锁后会从主存中读取,但我认为此时线程A还未把i=1从工作内存中刷新到主存吧,为什么这个同步代码块可以实现i的可见性。
相关代码
public class b {
public static int i;
public static void main(String[] args) throws Exception {
Object o = new Object();
new Thread(() -> { //线程A
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
i = 1;
while (true) {
}
}).start();
new Thread(() -> { //线程B
while (true) {
synchronized (o) { //加了这个同步代码块后线程B就能马上停止,里面什么都不写
}
if (i == 1) {
System.out.println("结束");
break;
}
}
}).start();
}
}
题目描述
题目来源及自己的思路
相关代码
// 请把代码文本粘贴到下方(请勿用图片代替代码)
首先在定义上:JMM关于synchronized的两条语义规定:
线程解锁前,必须把共享变量的最新之刷新到主内存中
线程加锁前,将清空工作内存中共享变量的值,从而使用共享变量时需要从主内存中重新读取最新的值
在实现上:无论是锁还是volatile的可见性都是通过内存屏障(Memnory Barrier)来实现的