正常情况
public class Test {
public static void main(String[] args) {
Demo demo = new Demo();
new Thread(() -> demo.setNum(10)).start();
new Thread(() -> System.out.println(demo.getNum())).start();
}
}
class Demo {
private int num = 1;
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
}
因为线程之间的不可见性,输出是1或10
加synchronized后,底层是通过monitorenter的指令来进行加锁的、通过monitorexit指令来释放锁的。
monitorenter指令还具有Load屏障的作用,synchronized内部的共享变量,每次读取数据时强制从主内存读取最新的数据。
monitorexit指令也具有Store屏障的作用,synchronized代码块内的共享变量,如果数据有变更的,强制刷新回主内存。
这样通过这种方式,数据修改之后立即刷新回主内存,其他线程进入synchronized代码块后,使用共享变量时强制读取主内存的数据,上一个线程对共享变量的变更操作,它就能立即看到了。
public class Test {
public static void main(String[] args) {
Demo demo = new Demo();
new Thread(() -> demo.setNum(10)).start();
new Thread(() -> System.out.println(demo.getNum())).start();
}
}
class Demo {
private int num = 1;
public synchronized int getNum() {
return num;
}
public synchronized void setNum(int num) {
this.num = num;
}
}