AtomicInteger详解
**上一篇文章谈到volatile不能保证原子性, 但如果业务需要原子性的时候, 需要用什么呢?**
- 使用synchronized, Lock 等加锁机制进行原子操作
- 使用原子操作类, java.util.concurrent.atomic下面的原子操作类进行原子操作
下面我们主要分析一下原子操作类AtomicInteget
AtomicInteget
代码演示
AtomicInteger b = new AtomicInteger();
@Test
public void testAtomicAdd() throws InterruptedException {
for (int i = 0; i < 100; i++) {
new Thread(() -> {
for (int j = 0; j < 1000; j++){
b.incrementAndGet();
}
}).start();
}
TimeUnit.SECONDS.sleep(1);
System.out.println("最后结果: " + b);
}
执行结果.png
源码分析.png
CAS 的缺点
- 循环时间开销很大(如果很到线程进行操作, 就会存在很多while循环, 导致CUP开销很大)
- 只能保证一个共享变量的原子操作
- 存在ABA问题
ABA问题分析.png
ABA问题解决
添加乐观锁机制, 增加一个版本号, 使用AtomicStampedReference类
ABA问题解决.png
总结
volatile可以理解为轻量级的synchronized, 最适用一个线程写,多个线程读的场合.若需要保证一个共享变量的原子性, 使用java.util.concurrent.atomic包下的原子操作类, 使用时需注意ABA问题.