深入了解多线程之可见性
最近在深入学习多线程的知识在此记录一下
并发编程三大特性有:可见性,有序性,原子性
可见性验证代码:
public class Visibility {
private static /** volatile */ boolean flag = true;
private static void m(){
System.out.println("m start");
while (flag){
}
System.out.println("m end");
}
public static void main(String[] args) throws Exception{
new Thread(Visibility::m,"t1").start();
Thread.sleep(1);
flag = false;
}
在这段代码中,按照正常的逻辑 m end 是应该会被打印的
但是因为多线程时,一个线程取到该值后有存在只读取缓存中的值内容的情况,就导致了程序会陷入死循环,而不会打印 m end的情况。
当然该情况不是每次都发生,可以多试几次。
当加入了 volatile关键字后即可保证 每一次 flag的值都可以及时的被刷新。
但是当 volatile 修饰对象时,将只保证对象引用的可见性,而不保证对象中属性的可见性,代码如下:
public class Visibility02 {
private static class A{
boolean flag = true;
void m(){
System.out.println("m start");
while (flag){}
System.out.println("m end");
}
}
private volatile static A a = new A();
public static void main(String[] args) throws Exception{
new Thread(a::m,"t1").start();
Thread.sleep(1);
a.flag = false;
}
所以当我们想保证对象中的属性的可见性时需要用volatile去修饰该属性.

浙公网安备 33010602011771号