AQS源码解析(一)-AtomicBoolean源码解析
2019-08-21 23:54
2136 查看
- 基本类: AtomicInteger
- AtomicLong
- AtomicBoolean
-
AtomicIntegerArray
介绍
由于在多线程条件下,如果对共享变量修改容易造成数据不一致的情况,所以对于共享变量需要保证线程安全有有如下几种方式:
- 使用
lock
或者synchronized
进行同步共享变量 - 使用CAS方法来保证修改变量为原子性操作
该类为后者,基于CAS方式修改具有原子性。
实现原理
- 将boolean中的true转换成
int
类型表示:1表示true 0表示false - 在类进行初始化的时候获取该值的内存地址
- 调用
Unsafe.compareAndSwant
方法底层通过CAS原理(CPU中cmpxchg指令)对值进行变化
特点
- 基于CAS实现线程安全
- 实现了
Cloneable
接口,能被克隆 - 实现了
Serializable
接口,支持序列化传输
源码解析
成员变量
private static final long serialVersionUID = 4654671469794556979L; // setup to use Unsafe.compareAndSwapInt for updates //使用unsafe类进行cas private static final Unsafe unsafe = Unsafe.getUnsafe(); //获取该值得偏移量(内存中的地址) private static final long valueOffset; /** * 内部使用int来做boolean的设置 * 默认为0 */ private volatile int value;
serialVersionUID
:序列化IDunsafe
:该类是Atomic中核心类,用于执行低级别,对内存进行操作,内部都是native
方法valueOffset
:字段value的内存偏移地址value
:真实value,1表示true 0表示false,使用volatile
保证内存可见性
类初始化过程
static { try { //返回对象成员属性在内存地址相对于此对象的内存地址的偏移量 valueOffset = unsafe.objectFieldOffset (AtomicBoolean.class.getDeclaredField("value")); } catch (Exception ex) { throw new Error(ex); } }
主要是通过unsafe方法获取value值得内存偏移地址
成员方法
get()
获取该boolean变量
/** * 返回当前值 */ public final boolean get() { return value != 0; }
boolean compareAndSet(boolean expect, boolean update)
比较前值后赋值,可能存在赋值失败的情况
/* * 只有当期待的值为expect的时候才会更新相关值 * 1. 期待的值等于现在值,则成功赋值,返回true * 2. 期待的值不等于现在的值,则赋值失败,则返回false */ public final boolean compareAndSet(boolean expect, boolean update) { int e = expect ? 1 : 0; int u = update ? 1 : 0; return unsafe.compareAndSwapInt(this, valueOffset, e, u); }
- 将boolean转换成int类型
- 调用
compareAndSwapInt
进行CAS赋值 - 返回true则表示成功,false表示失败
boolean getAndSet(boolean newValue)
比较前值后进行赋值,用的相对较多
public final boolean getAndSet(boolean newValue) { boolean prev; do { prev = get(); } while (!compareAndSet(prev, newValue)); return prev; }
- 先获取之前值
- 在调用循环
compareAndSet
进行CAS赋值
void set(boolean newValue)
无条件设置值,用的相对较少
public final void set(boolean newValue) { value = newValue ? 1 : 0; }
void lazySet(boolean newValue)
也是赋值操作,该操作会让Java插入StoreStore内存屏障,避免发生写操作重排序
public final void lazySet(boolean newValue) { int v = newValue ? 1 : 0; unsafe.putOrderedInt(this, valueOffset, v); }
总结
- 该类是原子性
boolean
类,是线程安全的 - 该原子类的核心操作都是基于Unsafe类
- CAS普遍会产ABA问题
相关文章推荐
- AtomicBoolean源码解析
- 读AtomicBoolean源码之浅析
- [Java多线程]-J.U.C.atomic包下的AtomicInteger,AtomicLong等类的源码解析
- lesson8:AtomicInteger源码解析及性能分析
- AbstractQueuedSynchronizer(AQS)源码解析-续
- AQS源码解析
- AtomicInteger源码解析
- AbstractQueuedSynchronizer(AQS)源码解析上
- AQS(AbstractQueuedSynchronizer)源码解析(共享锁部分)
- AbstractQueuedSynchronizer(AQS)源码解析下
- AtomicBoolean 源码分析
- ReactiveSwift源码解析(十一) Atomic的代码实现以及其中的Defer延迟、Posix互斥锁、递归锁
- JUC源码分析1-原子变量-AtomicInteger/AtomicBoolean/AtomicLong/AtomicReference
- Jdk1.6 JUC源码解析(1)-atomic-AtomicXXX
- AQS(AbstractQueuedSynchronizer)源码解析(ConditionObject)
- 6java源码解析-Boolean
- JDK 源码解析 —— AtomicInteger
- Java-Classloader-loadeClass(String,boolean)、findClass(String)类加载源码解析
- ReactiveSwift源码解析(十一) Atomic的代码实现以及其中的Defer延迟、Posix互斥锁、递归锁
- JDK之Boolean源码解析