ITPub博客

首页 > IT职业 > IT生活 > 怎样正确理解volatile?

怎样正确理解volatile?

原创 IT生活 作者:是一哥嘛 时间:2019-08-29 17:11:30 0 删除 编辑

volatile是java虚拟机提供的轻量级的同步机制

三大特征:

(1)保证可见性

当线程对变量进行操作时,必须在工作内存中进行,完成后再写会到主内存中。

在写回主内存中后其他线程马上都能看到,就是 钢边箱可见性

(2)不保证原子性

丢失写值的情况

(3)禁止指令重拍


JMM内存模型

可见性

原子性

有序性

主内存:主内存是共享内存的区域,相当于我们的内存条,里面存储共享变量,所有线程都能访问

工作内存:每个线程创建时JVM都会为其创建一个工作内存,工作内存里面存放的是该线程的私有数据,不能相互访问,

当线程对变量进行操作时,必须在工作内存中进行,完成后再写会到主内存中。

在写回主内存中后其他线程马上都能看到,就是可见性


什么是CAS(compareAndSet)?

比较并交换


AtomicInteger.compareAndSet(期望值,要修改的值)

期望值:从主物理内存中的值

线程每次修改值的时候都要从主物理内存中去获取并比较是否和期望值相同,如果和期望值相同,则修改成要修改的值,并返回true


CAS底层原理?

unsafe valueoffset(内存偏移地址)

Unsafe是CAS的核心类

atomicInteger.getAndIncrement();
底层源码:::::
public final int getAndIncrement() {
return unsafe.getAndAddInt(this, valueOffset, 1);
}
public final int getAndAddInt(Object var1, long var2, int var4) {
int var5;
do {
var5 = this.getIntVolatile(var1, var2);
} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
return var5;
}

假设 线程A 和 线程B 同时执行getAndAddInt操作,

首先线程A先从主内存中获取到变量A=3到自己的线程内存中,

同时线程B也从主内存中获取到变量A=3到自己的线程内存中,

现在AB线程中都有一份自己的内存变量A=3的副本,


线程A通过this.getIntVolatile(var1, var2);

获取到内存中的A=3,这时线程A被挂起。


这时线程B通过this.getIntVolatile(var1, var2);

获取到内存中的A=3,并执行了this.compareAndSwapInt(var1, var2, var5, var5 + var4)

比较主内存中的值也为3,就成功将自己的工作内存中的A修改为4并写回到主内存中。


这时线程A回复,执行compareAndSwapIn方法比较,发现自己工作内存中的A与主内存中的A

不一致,说明已经被其他线程修改过了,那线程A本次修改失败,while重新来一遍


线程A重新获取value,因为变量被volatile修饰,所以其他线程对他的修改线程A总是能看到

(volatile的可见性原理)线程A继续执行compareAndSwapInt进行比较直到成功

缺点:

循环时间开销很大

只能保证一个共享变量的原子操作

ABA问题(狸猫换太子)

CAS算法是提取内存中某时刻的数据并在当下时刻进行比较并替换,这个时间差会导致数据变化

比如T1从内存位置V中取出A,这时另一个线程T2也取出A,T2 将A–>B,然后T2又将B–>A,这

时T1进行CAS发现内存中还是A,然后线程T1就操作成功了


解决ABA问题:

原子引用AtomicReference

新增一种机制,修改版本号 AtomicStampedReference(初始值,初始版本号)

atomicStampedReference.compareAndSet(100,101,atomicStampedReference.getStamp(),atomicStampedReference.getStamp()+1);



来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69946594/viewspace-2655460/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2019-08-26

  • 博文量
    74
  • 访问量
    42389