必知必会:深入理解volatile

文章目录

好文

关于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 都不是原子操作,不适用

同步与锁

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

image-20220501192231483

image-20220501192306888

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

(这里写的汇编指令都简化记不一定是对的,明白意思就行)
原子操作是指: 单指令的操作
如: 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修改数值后会将其写回主存,通过总线嗅探机制一旦总线嗅探到某个线程修改了数值,
就将其他线程已经缓存的先前数值做废,重新读取主存内的值,所以可以保证可见性

为什么不能保证原子性:

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

书中精彩片段

在这里插入图片描述

image-20220501191659916

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值