美文网首页
为什么AtomicXXX是线程安全的累计计数

为什么AtomicXXX是线程安全的累计计数

作者: battle_ | 来源:发表于2017-07-12 17:01 被阅读15次

effective java 第66条内容说到,累计计数i++同步问题
一种是用sync修饰符进行同步操作

另一种是使用AtomicXXX变量,如AtomicLong 的 getAndIncrement方法

好奇AtomicLong的实现,原以为也是进行同步锁操作实现的原子性。
发现源码并不是这样做的,而是使用了native方法unsafe,改方法只能在授信的代码中实例化如jdk内。
代码如下

public final long getAndIncrement() {
        while (true) {
            long current = get();
            long next = current + 1;
            if (compareAndSet(current, next))
                return current;
        }
    }

compareAndSet

public final boolean compareAndSet(long expect, long update) {
        return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
    }

可以发现当进行累加操作时,第一时间没有进行对变量的更改操作
而是将累加结果保存,通过compareAndSet方法对变量更改,
使用unsafe CAS方法判断当前值与要累加的值expect对比,如果两个变量是同一个,则进行更改操作update->当前值,否则返回false CAS存在一个ABA问题,即当判断值A是否被修改前,该值被其他线程修改成了B,然后又被修改回了A,那么CAS仍然认为该值是没有被修改过的,进行赋值操作
而getAndIncrement原理就是,不断的loop循环判断,当前值有没有在累加操作前被其他线程修改了,如果没改就赋值,改了就重新累加,再判断赋值。从而形成了类似同步的机制。保证变量的原子性。

相关文章

  • 为什么AtomicXXX是线程安全的累计计数

    effective java 第66条内容说到,累计计数i++同步问题一种是用sync修饰符进行同步操作 另一种是...

  • Atomic类&LongAdder

    Atomic原子类 以AtomicXXX开头的都是用CAS操作来保证线程安全的类。 在开发工作中经常有多个线程共同...

  • 线程安全的计数

  • 计数器

    讲讲Java里计数器问题,对于理解原子性很有帮助。 线程安全的计数器 与 线程不安全的计数器 直接上代码,代码里实...

  • AtomicInteger 类

    自增操作符(++),非原子性,线程不安全。线程安全的计数采用 synchronized 或 AtomicInteg...

  • Concurrent Java 01 - 线程安全性

    线程安全三个必要性 原子性 Atomic 包提供了一批AtomicXXX类型,用于确保对象的获取和操作步骤为原子性...

  • iOS-线程安全探究

    为什么CFRunLoopRef是线程安全的,而基于此的NSRunLoop却不是线程安全的呢? 线程安全时多线程领域...

  • synchronized到底锁住的是谁?

    题目:利用5个线程并发执行,num数字累计计数到10000,并打印。 1 /** 2 * Description:...

  • 面试题收集

    一面HashMap 是线程安全的吗?Hashtable为什么是线程安全的? ConcurrentHashmap怎么...

  • HashMap相关

    HashMap是数组+链表 1.HashMap不是线程安全,为什么不是线程安全的呢? 多线程put,多线程reha...

网友评论

      本文标题:为什么AtomicXXX是线程安全的累计计数

      本文链接:https://www.haomeiwen.com/subject/tvdbhxtx.html