• 【面试:并发篇29:多线程:volatile】原理


    【面试:并发篇29:多线程:volatile】原理

    00.前言

    如果有任何问题请指出,感谢。

    01.介绍

    volatile的底层实现原理是内存屏障

    1.对volatile变量的写指令后会加入写屏障
    2.对volatile变量的读指令前会加入读屏障

    02.volatile保证可见性原理

    写屏障:保证在该屏障之前的,对共享变量的改动都同步到主存当中。

    	public void actor2(I_Result r){
    		num = 2;
    		ready = true; // ready是volatile修饰的,且ready是写操作
    		// ready后有写屏障
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5

    读屏障:保证在该屏障之后,对共享变量的读取,加载的是主存中的最新数据

    	public void actor1(I_Result r){
    		// 因为ready是读操作
    		// 在ready之前有读屏障
    		if(ready){
    			r.r1 = num + num;
    		}else{
    			r.r1 = 1;
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    解释

    写屏障可以保证自己和自己之前的共享变量 都同步到主存中,就像这里的num = 2是在ready = true之前,那么共享变量ready与num都会同步到主存当中
    读屏障则是可以保证自己和自己之后的共享变量读取都是最新的,例如这里if(ready)就读取了ready 还有 r.r1 = num + num,这里读取了num
    总结:通过读写屏障保证了 加了volatile的变量不论是写还是对都是最新的数据,且 对于写之前 读之后的数据也都是最新数据。这就是可见性实现的原理。

    03.volatile保证有序性原理

    写屏障:确保指令重排序时,不会将写屏障之前的代码排在写屏障之后。

    	public void actor2(I_Result r){
    		num = 2;
    		ready = true; // ready是volatile修饰的,且ready是写操作
    		// ready后有写屏障
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5

    读屏障:确保指令重排序时,不会将读屏障之后的代码排在读屏障之前。

    	public void actor1(I_Result r){
    		// 因为ready是读操作
    		// 在ready之前有读屏障
    		if(ready){
    			r.r1 = num + num;
    		}else{
    			r.r1 = 1;
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    解释

    写屏障确保指令重排序时,不会将写屏障之前的代码排在写屏障之后,例如这个例子中的ready = true是读操作,保证了ready之前的代码不会出现在ready之后
    读屏障则是确保指令重排序时,不会将读屏障之后的代码排在写屏障之前,例如这个例子中的if(ready)保证了ready之后的代码不会出现在ready之前,不过这里ready不存在这个问题 因为这里只有ready为true时才能进入
    总结:通过读写屏障保证了 加了volatile的变量写之前的代码不会出现在写屏障之后 这就保证了 这个变量的位置固定,同时读屏障保证了读屏障之后的代码不会出现在读屏障之前 也保证了位置固定,所以在写这个变量时 这个变量不会出现指令重排序,读这个变量时 这个变量也不会出现指令重排序,保证了有序性。

  • 相关阅读:
    Codeforces Round #827 (Div. 4)
    工业自动化应用智能制造技术有哪些作用?
    批量提取图片文件名使用Python中os.listdir( )函数时出现文件名乱序,非预想排序的解决方法
    Android Gradle 开发与应用 (一) : Gradle基础
    若依框架使用localStorage代替Cookie?
    Qt窗体设计的布局
    vivo 手机云服务建设之路-平台产品系列04
    【List篇】ArrayList 的线程不安全介绍
    LabVIEW建立生产者消费者
    【期权系列】期权市场 PCR 指标的策略应用
  • 原文地址:https://blog.csdn.net/m0_71229547/article/details/126062036