原子操作类 ——AtomicLong简单介绍

原子操作类 ——AtomicLong

public class AtomicLongTest {

    private static Random random = new Random(2);
        //定义一个Long类型的原子计数器
    private static AtomicLong count = new AtomicLong();

    public static void main(String[] args) throws Exception {
        //(1)获取两组随机数,每组20个
        List<Integer> list1 = new ArrayList<>(20);
        List<Integer> list2 = new ArrayList<>(20);
        //(2)获取时记录可以被3除余数为0的数的的个数
        long j = 0;
        for (int i = 0; i < 20; i++) {

            int a = random.nextInt(50);
            System.out.print(a + " ");
            list1.add(a);
            if (a % 3 == 0) {
                j ++;
            }

            int b = random.nextInt(50);
            System.out.print(b  + " ");
            list2.add(b);

            if (b % 3 == 0) {
                j ++;
            }
        }

        //(3)开启一个线程计算出list1中可以被3除,余数为0的数的个数,进行count.getAndIncrement()操作
        Thread thread1 = new Thread(() -> {
            for (Integer a : list1) {
                if (a % 3 == 0) {
                    count.getAndIncrement();
                }
            }
        });

        //(4)再开启一个线程计算出list2中可以被3除,余数为0的数的个数,进行count.getAndIncrement()操作
        Thread thread2 = new Thread(() -> {
            for (Integer a : list2) {
                if (a % 3 == 0) {
                    count.getAndIncrement();
                }
            }
        });
        //启动thread1和thread2
        thread1.start();
        thread2.start();

        //等待thread1和thread2执行完
        thread1.join();
        thread2.join();

        System.out.println();
        System.out.println("j = " + j);
        System.out.println("count = " + count);
    }
}

输出结果为

8 22 40 17 39 0 6 19 47 18 44 36 34 14 14 16 17 49 30 31 28 47 49 42 6 14 12 35 3 12 29 26 7 0 30 24 47 15 17 38 
j = 15
count = 15

在多线程的情况下,count的值喝j的值始终保持相等;因为在AtomicLong中都是用了CAS非阻塞算法;

  • final long getAndIncrement()
    public final long getAndIncrement() {
        return unsafe.getAndAddLong(this, valueOffset, 1L);
    }
  • final long getAndAddLong(Object var1, long var2, long var4)
    public final long getAndAddLong(Object var1, long var2, long var4) {
        long var6;
        do {
            var6 = this.getLongVolatile(var1, var2);
        } while(!this.compareAndSwapLong(var1, var2, var6, var6 + var4));

        return var6;
    }

这里虽然使用了CAS非阻塞算法,性能方面比使用Synchronized关键字,获取其他锁机制要高很多,但是还有更急优秀的方式,后续再说;

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

推荐阅读更多精彩内容