AtomicInteger代替volatile

AtomicInteger详解

**上一篇文章谈到volatile不能保证原子性, 但如果业务需要原子性的时候, 需要用什么呢?**

  1. 使用synchronized, Lock 等加锁机制进行原子操作
  2. 使用原子操作类, 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 的缺点

  1. 循环时间开销很大(如果很到线程进行操作, 就会存在很多while循环, 导致CUP开销很大)
  2. 只能保证一个共享变量的原子操作
  3. 存在ABA问题
ABA问题分析.png

ABA问题解决

添加乐观锁机制, 增加一个版本号, 使用AtomicStampedReference类

ABA问题解决.png

总结

volatile可以理解为轻量级的synchronized, 最适用一个线程写,多个线程读的场合.若需要保证一个共享变量的原子性, 使用java.util.concurrent.atomic包下的原子操作类, 使用时需注意ABA问题.

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容