前言
原子类继承于 Number 接口 , 归属于java.util.concurrent.atomic 包中 , 原子类的主要作用是为了解决 synchronized 处理原子操作 资源消耗过高 的问题 ,原子类的CAS 基于 Unsafe 实现 .
一. 原子类的简述
1.1 原子类的应用场景
原子类适用于需要原子操作而有需要减少资源消耗时 , 原子类相当于 volatile 和 CAS 的工具类 .
1.2 原子类的类型
基本类型 : 使用原子的方式更新基本类型
- AtomicInteger:整形原子类
- AtomicLong:长整型原子类
- AtomicBoolean :布尔型原子类
数组类型 : 使用原子的方式更新数组里的某个元素
- AtomicIntegerArray:整形数组原子类
- AtomicLongArray:长整形数组原子类
- AtomicReferenceArray :引用类型数组原子类
引用类型
- AtomicReference:引用类型原子类
- AtomicStampedRerence:原子更新引用类型里的字段原子类
- AtomicMarkableReference :原子更新带有标记位的引用类型
对象的属性修改类型
- AtomicIntegerFieldUpdater:原子更新整形字段的更新器
- AtomicLongFieldUpdater:原子更新长整形字段的更新器
- AtomicStampedReference :原子更新带有版本号的引用类型。
- 该类将整数值与引用关联起来
- 可用于解决原子的更新数据和数据的版本号
- 可以解决使用 CAS 进行原子更新时可能出现的 ABA 问题。
1.3 . AtomicInteger 类常用方法
- public final int get() : 获取当前的值java
- public final int getAndSet(int newValue) : 获取当前的值,并设置新的值
- public final int getAndIncrement(): 获取当前的值,并自增
- public final int getAndDecrement() : 获取当前的值,并自减
- public final int getAndAdd(int delta) : 获取当前的值,并加上预期的值
- boolean compareAndSet(int expect, int update) : 如果输入的数值等于预期值,则以原子方式将该值设置为输入值(update)
- public final void lazySet(int newValue) : 最终设置为newValue,使用 lazySet 设置之后可能导致其他线程在之后的一小段时间内还是可以读到旧的值。
- public final int incrementAndGet() : 以原子方式给当前值加1并获取新值
- public final int decrementAndGet() : 以原子方式给当前值减1并获取新值
- public final int addAndGet(int delta) : 以原子方式给当前值加delta并获取新值
- public final boolean compareAndSet(int expect, int update) : CAS 比较方法
二 . 原子类的原理
2.1 原理简述
原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,中间不会有任何 contextswitch切换到另一个线程 , 之所以称为原子变量,是因为其包含一些以原子方式实现组合操作的方法
回顾 CAS : CAS的原理是拿期望的值和原本的一个值作比较,如果相同则更新成新的值
原子类主要通过 CAS (compare and swap) + volatile 和 native 方法来保证原子操作 !
1 | JAVA复制代码// 案例 : AtomicInteger |
- 先获取当前值current,计算期望的值next
- 然后调用CAS方法进行更新,如果当前值没有变,则更新并返回新值,否则继续循环直到更新成功为止
2.2 AtomicInteger 原理深入
我们从源码看看那些之前被我们忽略的东西 , 此类可以代表大多数基本类型
1 | java复制代码 |
2.3 AtomicReference 深入
现在看一下 AtomicReference 有什么特别之处
1 | java复制代码 |
2.4 AtomicIntegerArray 深入
相对而言 AtomicIntegerArray 有更多得变化 , 其他的大同小异
1 | java复制代码 |
三 . 原子类的操作
3.1 原子类常见案例
1 | java复制代码AtomicInteger integer = new AtomicInteger(); |
3.2 原子类测试多线程情况
1 | java复制代码 /** |
欢迎大家关注我的相关文档 多线程集合
参考文档
1 | java复制代码[芋道源码](http://www.iocoder.cn/JUC/sike/aqs-3/) |
本文转载自: 掘金