必知必会:深入理解volatile

必知必会:深入理解volatile,第1张

文章目录
    • 好文
    • 理解,总结

好文
关于Java并发编程Volatile 关键字讲解最好的一篇文章Java面试热门内容精讲之——并发编程volatile (视频)
DMA和cache一致性问题DMA导致的CACHE一致性问题解决方案
volatile 关键字,你真的理解吗?8.volatile为啥不能保证原子性?
7.volatile怎么通过内存屏障保证可见性和有序性?多线程编程中什么情况下需要加 volatile?

书<<程序员的自我修养>>

视频: 程序员的自我修养视频教程

理解,总结
volatile 只能保证可见性,不能保证原子性
两个作用: 1. 阻止编译器对volatile变量指令的重排优化
		2.  阻止编译器为了提高速度而将一个变量缓存到寄存器而不写回。
volatile适用于纯赋值 *** 作,如 a = 2 (其经过三步 : 1. load a to register 2. 将寄存器中的值++ 3. 将寄存器中的值写回主存)
注意 : 如 a++ \ a = !a 都不是原子 *** 作,不适用

同步与锁

常用的锁: 二元信号量 、 (多元)信号量、互斥量 、 临界区 、 读写锁、条件变量

先要明白为什么自增不是原子 *** 作

(这里写的汇编指令都简化记不一定是对的,明白意思就行)
原子 *** 作是指: 单指令的 *** 作
如: a = 2	mov a, 2

++a在很多体系上的实现如下:
1.读取a 到某个寄存器X	mov X,a
2.X++				 add X, 1
3.将X的内容存储回a		mov a, X

先讲一下指令重排为什么可以优化速度

重排前:
    a = 2; //1. load(加载进寄存器) 2. set(设置为2) 3. store(写回)
    b = 4;//1. 2. 3.
    a = a + 1;//1. 2. 3.
    一共9步 *** 作
重排 : 
	a = 2;//1.load 2.set 先不写回
	a = a + 1;//3. set 4.store
	b = 4;//1. 2. 3.
	一共7步 *** 作,优化了速度

volatile 如何保证数据的可见性:

volatile修改数值后会将其写回主存,通过总线嗅探机制一旦总线嗅探到某个线程修改了数值,
就将其他线程已经缓存的先前数值做废,重新读取主存内的值,所以可以保证可见性

为什么不能保证原子性:

不能保证原子性的关键在于,读 *** 作的时候,读取到相同的数据,但是在写入时其中某个线程因为阻塞等原因,
存在一种情况,即这个线程的写 *** 作不在另一个线程修改完变量回写时的加锁时间区间,导致这个线程的写 *** 作
覆盖了另一个线程的写 *** 作。

书中精彩片段

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/794551.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-06
下一篇 2022-05-06

发表评论

登录后才能评论

评论列表(0条)

保存