线程安全的实现方法有哪些?
- 互斥同步:synchornized和ReentrantLock
- 非阻塞同步:CAS,AtomicXXX类
- 无同步方案:栈封闭,Thread Local ,可重入代码
什么是CAS?
CAS(Compare-And-Swap)比较兑换
CompareAndSwap(期望值,目标值)
接收变量对象,如果变量对象是所期望的值,就交换目标值给该变量
CAS操作具有原子性,所以一般不会加锁CAS属于乐观锁,synchronize属于悲观锁
CAS使用示例,结合AtomicInteger给出示例?
看以下源码可知:
如果当前值==预期值,则自动将值设置为给定的更新值。
参数:
期望——期望值
更新 - 新值
回报:如果成功,则为true 。 False return 表示实际值不等于预期值。
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
看到这个方法即可知,在源码里使用了CAS原理来进行赋值,保证了多线程的安全可靠性
CAS会有哪些问题? 针对这这些问题,Java提供了哪几个解决的?
- ABA问题(也就是原来的值其实改变过但是,换值的时候却没有侦查到值的改动过)
- 循环时间长开销大
- 只能保证一个共享变量的原子操作
1 => ABA的解决方案 在变量前面加上版本号即可
2 => JVM处理器能够支持pause指令延迟流水线命令以及避免退出循环时内存顺序冲突而引起cpu流水线被清空
3 => 从Java 1.5开始,JDK提供了AtomicReference类来保证引用对象之间的原子性,就可以把多个变量放在一个对象里来进行CAS操作。
AtomicInteger底层实现?
AtomicInteger实际上底层是unsafe实现的
底层用的是volatile的变量和CAS来进行更改数据的。
volatile保证线程的可见性,多线程并发时,一个线程修改数据,可以保证其它线程立马看到修改后的值
CAS 保证数据更新的原子性。
请阐述你对Unsafe类的理解?
如其名,主要提供一些用于执行低执行力,不安全操作的方法,如直接访问系统内存资源,自主管理内存资源等、这些方法大大提升了java运行效率,但由于unsafe类使java拥有了同c语言指针一样操控内存空间的呢能力,增加了程序发生相关指针问题的风险
,Unsafe提供的API大致可分为内存操作、CAS、Class相关、对象操作、线程调度、系统信息获取、内存屏障、数组操作等几类,下面将对其相关方法和应用场景进行详细介绍。
说说你对Java原子类的理解? 包含13个,4组分类,说说作用和使用场景。
另一种实现线程同步的解决方案,并且
1、 简单:操作简单,底层实现简单
2、 高效:占用资源少,操作速度快
3、 安全:在高并发和多线程环境下要保证数据的正确性
- 原子更新基本类型(使用原子的方式更新基本类型)
- AtomicBoolean:原子更新布尔类型
- AtomicInteger:原子更新整形
- AtomicLong:原子更新长整型
- 原子更新数组
- AtomicIntegerArray:原子更新整型数组里的元素。
- AtomicLongArray: 原子更新长整型数组里的元素。
- AtomicReferenceArray: 原子更新引用类型数组里的元素。
- 原子更新引用类型
- AtomicReference: 原子更新引用类型。
- AtomicStampedReference: 原子更新引用类型, 内部使用Pair来存储元素值及其版本号。
- AtomicMarkableReferce: 原子更新带有标记位的引用类型。
- 原子更新字段类型
- AtomicIntegerFieldUpdater: 原子更新整型的字段的更新器。
- AtomicLongFieldUpdater: 原子更新长整型字段的更新器。
- AtomicStampedFieldUpdater: 原子更新带有版本号的引用类型。
- AtomicReferenceFieldUpdater: 上面已经说过此处不在赘述。
AtomicStampedReference是什么?
AtomicStampedReferences是jdk用于处理cas(解决了了)ABA操作的类
AtomicStampedReference是怎么解决ABA的?
AtomicStampedReference给每一个需要操作的值增加了一个版本号。用于识别每一个值是否版本对应,就可以看出值是否有变化
内部使用Pair来存储元素值及其版本号 java中还有哪些类可以解决ABA的问题?
AtomicMarkableReference,它不是维护一个版本号,而是维护一个boolean类型的标记,标记值有修改