A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

请谈谈你对volatile的理解?

    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<T>
新增一种机制,修改版本号  AtomicStampedReference(初始值,初始版本号)
atomicStampedReference.compareAndSet(100,101,atomicStampedReference.getStamp(),atomicStampedReference.getStamp()+1);   
                                                                        期望值,要修改的值,期望版本号,要修改的版本号

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马