AtomicInteger

AtomicInteger 能解决什么问题?什么时候使用 AtomicInteger?

支持原子更新的 int 值。

如何使用 AtomicInteger?

1)需要被多线程并发访问的原子计数器。
2)使用 AtomicInteger.compareAndSet 实现非阻塞的线程安全工具类。

使用 AtomicInteger 有什么风险?

1)高并发场景下,自旋 CAS 长时间失败会导致 CPU 飙升,推荐使用 LongAdder。

AtomicInteger 核心操作的实现原理?

创建实例

    /**
* 可原子更新的 int 值
*/
private volatile int value; /**
* 创建初始值为 initialValue 的新 AtomicInteger 实例
*/
public AtomicInteger(int initialValue) {
value = initialValue;
} /**
* 创建初始值为 0 的新 AtomicInteger 实例
*/
public AtomicInteger() {
}

尝试以原子的方式更新值

    /**
* 如果当前值 == 预期值,则以原子方式将当前值设置为给定的更新值
* with memory effects as specified by {@link VarHandle#compareAndSet}.
*/
public final boolean compareAndSet(int expectedValue, int newValue) {
return U.compareAndSetInt(this, AtomicInteger.VALUE, expectedValue, newValue);
}

读取值

    /**
* 读取值
* with memory effects as specified by {@link VarHandle#getVolatile}.
*/
public final int get() {
return value;
}

以原子方式将当前值加 1,并返回旧值

    /**
* 以原子方式将当前值加 1,并返回旧值。
* with memory effects as specified by {@link VarHandle#getAndAdd}.
*/
public final int getAndIncrement() {
return U.getAndAddInt(this, AtomicInteger.VALUE, 1);
} Unsafe#
/**
* 1)原子地将给定的值累加到当前值、或指定索引为 offset 的数组元素上。
*/
@HotSpotIntrinsicCandidate
public int getAndAddInt(Object o, long offset, int delta) {
int v;
do {
// 以 volatile 的方式读取值
v = getIntVolatile(o, offset);
} while (!weakCompareAndSetInt(o, offset, v, v + delta));
// 返回旧值
return v;
} @HotSpotIntrinsicCandidate
public boolean weakCompareAndSetInt(Object o, long offset,
int expected,
int x) {
return compareAndSetInt(o, offset, expected, x);
} /**
* 如果当前值是 expected,则将目标值更新为 x,该操作具有 volatile 读和写内存语义。
* <p>This operation has memory semantics of a {@code volatile} read
* and write. Corresponds to C11 atomic_compare_exchange_strong.
*/
@HotSpotIntrinsicCandidate
public native boolean compareAndSetInt(Object o, long offset,
int expected,
int x);

以原子方式写入新值,并返回旧值

    /**
* 以原子方式写入新值,并返回旧值
* with memory effects as specified by {@link VarHandle#getAndSet}.
*/
public final int getAndSet(int newValue) {
return U.getAndSetInt(this, AtomicInteger.VALUE, newValue);
}

以原子方式将当前值减 1,并返回旧值

    /**
* 以原子方式将当前值减 1,并返回旧值
* with memory effects as specified by {@link VarHandle#getAndAdd}.
*/
public final int getAndDecrement() {
return U.getAndAddInt(this, AtomicInteger.VALUE, -1);
}

以原子方式将给定值与当前值相加,并返回旧值

    /**
* 以原子方式将给定值与当前值相加,并返回旧值
* with memory effects as specified by {@link VarHandle#getAndAdd}.
*/
public final int getAndAdd(int delta) {
return U.getAndAddInt(this, AtomicInteger.VALUE, delta);
}

原子更新当前值为函数式接口 updateFunction 的计算值,并返回旧值

    /**
* 原子更新当前值为函数式接口 updateFunction 的计算值,并返回旧值。
*/
public final int getAndUpdate(IntUnaryOperator updateFunction) {
// 读取旧值
int prev = get(), next = 0;
for (boolean haveNext = false;;) {
if (!haveNext) {
// 计算新值
next = updateFunction.applyAsInt(prev);
}
// 原子更新值,如果成功则返回旧值
if (weakCompareAndSetVolatile(prev, next)) {
return prev;
}
// 更新失败则重新读取旧值,如果出现 ABA 问题,则不会重新计算
haveNext = prev == (prev = get());
}
}

原子更新当前值为函数式接口 accumulatorFunction 的计算值,并返回旧值

    /**
* 原子更新当前值为函数式接口 accumulatorFunction 的计算值,并返回旧值
*/
public final int getAndAccumulate(int x,
IntBinaryOperator accumulatorFunction) {
// 读取旧值
int prev = get(), next = 0;
for (boolean haveNext = false;;) {
if (!haveNext) {
// 基于旧值和 x 计算新值
next = accumulatorFunction.applyAsInt(prev, x);
}
// 原子更新旧值
if (weakCompareAndSetVolatile(prev, next)) {
return prev;
}
haveNext = prev == (prev = get());
}
}

以原子方式将当前值加 1,并返回新值

    /**
* 以原子方式将当前值加 1,并返回新值
* with memory effects as specified by {@link VarHandle#getAndAdd}.
*/
public final int incrementAndGet() {
return U.getAndAddInt(this, AtomicInteger.VALUE, 1) + 1;
}

以原子方式将当前值减 1,并返回新值

    /**
* 以原子方式将当前值减 1,并返回新值
* with memory effects as specified by {@link VarHandle#getAndAdd}.
*/
public final int decrementAndGet() {
return U.getAndAddInt(this, AtomicInteger.VALUE, -1) - 1;
}

以原子方式将给定值与当前值相加,并返回新值

    /**
* 以原子方式将给定值与当前值相加,并返回新值
* with memory effects as specified by {@link VarHandle#getAndAdd}.
*/
public final int addAndGet(int delta) {
return U.getAndAddInt(this, AtomicInteger.VALUE, delta) + delta;
}

以原子方式更新值【新值通过函数式接口计算得到,参数为旧值】,并返回新值

    /**
* 以原子方式更新值【新值通过函数式接口计算得到,参数为旧值】,并返回新值。
*/
public final int updateAndGet(IntUnaryOperator updateFunction) {
int prev = get(), next = 0;
for (boolean haveNext = false;;) {
if (!haveNext) {
next = updateFunction.applyAsInt(prev);
}
if (weakCompareAndSetVolatile(prev, next)) {
return next;
}
haveNext = prev == (prev = get());
}
}

以原子方式更新值【新值通过函数式接口计算得到,参数为旧值和参考更新值】,并返回新值

    /**
* 以原子方式更新值【新值通过函数式接口计算得到,参数为旧值和参考更新值】,并返回新值
*/
public final int accumulateAndGet(int x,
IntBinaryOperator accumulatorFunction) {
int prev = get(), next = 0;
for (boolean haveNext = false;;) {
if (!haveNext) {
next = accumulatorFunction.applyAsInt(prev, x);
}
if (weakCompareAndSetVolatile(prev, next)) {
return next;
}
haveNext = prev == (prev = get());
}
}

最新文章

  1. C#调用百度高精度IP定位API通过IP获取地址
  2. Cookie使用时需要注意个数及大小限制
  3. 学习下nginx负载均衡--深入理解nginx
  4. button事件驱动
  5. MVC3 FAQ
  6. jQuery - AJAX (keep for myself)
  7. jQuery.inArray 方法的实现
  8. 【Android】BroadCast广播机制应用与实例
  9. cf581B Luxurious Houses
  10. iOS断点及打印日志
  11. 国内外主流BI厂商对比
  12. 关于Cookie中不过滤“=”号的方法
  13. How to make sure your machine is always online without sleep
  14. JavaScript配合button.onclick()使用总结
  15. SpringBoot1-创建SpringBoot项目
  16. 『TensorFlow』流程控制之tf.identity
  17. Jmeter进阶篇之保存测试结果
  18. 论文笔记:Variational Capsules for Image Analysis and Synthesis
  19. PropertyGrid中的枚举显示为中文
  20. 集合_java集合框架

热门文章

  1. Hyper-V Centos7 虚拟机固定IP
  2. 排列perm HYSBZ - 1072(状压dp/暴力)
  3. C#多播委托详解
  4. 前端校招知识体系之HTML5
  5. redis基础及redis特殊场景使用描述
  6. mailaddr - 关于邮件地址的描述
  7. /proc/sys/fs/file-max
  8. CSS初识
  9. PAT Advanced 1006 Sign In and Sign Out (25 分)
  10. Python内置函数之filter map reduce