JDK中原子性的支持

纵饮孤独 提交于 2019-12-04 13:24:18

在Java开发中,假设对共享变量除了赋值之外并不完成其他操作, 那么可以将这些共享变量声明为 volatile 或者final。

然而经常我们除了对共享变量赋值之外,还需要对共享变量进行修改操作,比如自增,自减等系列操作,那么此时就需要保证共享变量的原子性,所谓原子性,就是站在机器的角度,一个不可分隔的执行单元。在JDK中,java.util.concurrent.atomic 包中有很多类使用了很高效的机器级指令(而不是使用 锁) 来保证其他操作的原子性。

比如说AtomicLong类,提供了方法 incrementAndGet 和 decrementAndGet, 它们分别以原子方式将一个整数自增或自减。例如, 可以安全地生成一个 数值序列,像这样:

    public static AtomicLong atomicLong = new AtomicLong(1);

    public static void main(String[] args) {

        long res = atomicLong.incrementAndGet();

        System.out.println(res);
    }
  • incrementAndGet 方法以原子方式将 AtomicLong 自增, 并返回自增后的值。 也就是说, 获得值、 增 1 并设置然后生成新值的操作不会中断。 可以保证即使是多个线程并发地访问同一个实例, 也会计算并返回正确的值。

除了上述的简单incrementAndGet,原子类中还提供了系列两个以上的原子操作:

其他的原子类也具备类似的方法

如果有大量线程要访问相同的原子值, 性能会大幅下降, 因为乐观更新需要太多次重 试。

Java SE 8 提供了 LongAdder 和 LongAccumulator 类来解决这个问题。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!