Java源码Atomic部分源码解析
Posted 低调的洋仔
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java源码Atomic部分源码解析相关的知识,希望对你有一定的参考价值。
AtomicXXX
加了volatile保证了可见性。
本质上这一系列的都是采用的CAS的方式来更新原来的值的。
boolean实际上是用的int值来存储的。
AtomicXXXArray
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final int base = unsafe.arrayBaseOffset(long[].class);
private static final int shift;
private final long[] array;
基本的操作大体的意思应该是:
计算出来的地址就是:基础地址+偏移量=最终要定位的元素的地址。
然后Cas操作修改这个地址上的数据。
AtomicReferenceArray里面多了一个arrayFieldOffset,这个域用来支持反序列化的。其次,与AtomicIntegerArray不同,AtomicReferenceArray并没有scale域,取而代之的是shift域。阅读代码可知,其实目的都是计算rawIndex = base + index * scale,只不过AtomicReferenceArray里面把一部分运算转换为等价的位操作(当然前提是scala为2的幂)。(了解更多位操作技巧,可参考Hacker's Delight)。
public final void set(int i, long newValue)
unsafe.putLongVolatile(array, checkedByteOffset(i), newValue);
AtomicXXXFieldUpdater
- 原子域更新器,一般用于一些原子同步结构中。
/**
* Standard hotspot implementation using intrinsics
*/
private static class AtomicIntegerFieldUpdaterImpl<T> extends AtomicIntegerFieldUpdater<T>
private static final Unsafe unsafe = Unsafe.getUnsafe();
private final long offset;
private final Class<T> tclass;
private final Class cclass;
AtomicIntegerFieldUpdaterImpl构造过程中会目标class,和目标域的访问权限、还要要检查目标域是否为int型,是否由volatile修饰、当然还要获取目标域的偏移量,为后面的CAS操作做准备。
AtomicLongFieldUpdater,结构和AtomicIntegerFieldUpdater类似,有一点区别就是,它有两个实现,根据平台是否支持8字节的CAS操作,来选择不同的实现
AtomicReferenceFieldUpdater和AtomicIntegerFieldUpdater类似的结构,AtomicReferenceFieldUpdater一般用于某些原子数据结构中,支持某些节点的引用域的独立原子更新操作。
其实直接使用AtomicReference也可以完成类似的工作,那么为什么要使用AtomicReferenceFieldUpdater?主要原因还是为了提高性能。假设要设计一个支持原子操作的队列,队列的链接节点必然会进行频繁的操作,如果利用AtomicReference表示这些结点,那么AtomicReference本身的创建过程也需要一些开销,使用AtomicReferenceFieldUpdater可以省去这些开销。辅助创建一个实例,
AtomicStampedReference & AtomicMarkableReference
防止ABA问题,分别靠时间戳和Mark标记位来方式ABA问题的发生。
private static class Pair<T>
final T reference;
final int stamp;
private Pair(T reference, int stamp)
this.reference = reference;
this.stamp = stamp;
static <T> Pair<T> of(T reference, int stamp)
return new Pair<T>(reference, stamp);
private static class Pair<T>
final T reference;
final boolean mark;
private Pair(T reference, boolean mark)
this.reference = reference;
this.mark = mark;
static <T> Pair<T> of(T reference, boolean mark)
return new Pair<T>(reference, mark);
以上是关于Java源码Atomic部分源码解析的主要内容,如果未能解决你的问题,请参考以下文章
Java 集合系列11之 Hashtable详细介绍(源码解析)和使用示例
Java 集合系列06之 Vector详细介绍(源码解析)和使用示例