并发编程 - Atomic & Unsafe
1. 全面地走一遍Atomic包下面的原子类;
2. CAS -> 原子比较与交换算法的bug-ABA 问题;
3. 魔法类 - Unsafe,ini -> 堆外内存
Atomic
1. atomic底层实现是基于无锁算法 - cas;
基于魔术类Unsafe提供的三大cas-api完成;
CompareAndSwapObject
CompareAndSwapInt
CompareAndSwapLong
基于硬件原语-CMPXCHG实现原子操作cas
// AtomicInteger分析 do { oldValue = this.getIntVolatile(AtomicInteger, valueOffset); // 读AtomicInteger的value值 // valueOffset---value属性在对象内存当中的偏移量 }while(!this.compareAndSwapInt(AtomicInteger, valueOffset, oldValue, oldValue + 1));
什么叫偏移量?
要用cas修改某个对象属性的值 -》 首先要知道属性在对象内存空间的哪个位置,要知道属性的偏移量。
如果要修改的是一个数组类型,该怎么办呢?,Atomic也给我们提供了如下方式处理方案:
如果不是整形值,而是对象类型数据,Atomic也提供了解决方案。
如果觉得自定义实现UnSafe去获取偏移量,修改值的方法太麻烦,Atomic也提供了如下方式:
还可以基于上述说的基于最原始的Unsafe获取偏移量,基于cas去修改值:
Unsafe类的对象获取方式如下:
如果说要改的是一个成员属性是一个对象,而不是Integer数字类型,Atomic也提供了方案如下:
CAS修改的ABA问题
ABA ->怎么解决?
AtomicStampedReference
参考:https://baijiahao.baidu.com/s?id=1648077822185803003&wfr=spider&for=pc
Unsafe
jdk1.7之后添加的api
内存管理:
举个例子:文件上传,并发量也比较高;可以用Unsafe申请堆外内存。
堆外内存不属于GC管理,用完之后一定要手动释放。否则内存泄露。
Unsafe还提供了跨方法加锁机制。(不建议使用)