域名

Java并发编程包中atomic的实现原理

字号+作者:益华科技来源:应用开发2025-11-05 08:30:11我要评论(0)

这是一篇来自粉丝的投稿,作者【林湾村龙猫】最近在阅读Java源码,这一篇是他关于并发包中atomic类的源码阅读的总结。Hollis做了一点点修改。引子在多线程的场景中,我们需要保证数据安全,就会考虑

 这是并发编程包中一篇来自粉丝的投稿,作者【林湾村龙猫】最近在阅读Java源码,现原这一篇是并发编程包中他关于并发包中atomic类的源码阅读的总结。Hollis做了一点点修改。现原

引子

在多线程的并发编程包中场景中,我们需要保证数据安全,现原就会考虑同步的并发编程包中方案,通常会使用synchronized或者lock来处理,现原使用了synchronized意味着内核态的并发编程包中一次切换。这是现原一个很重的操作。

有没有一种方式,并发编程包中可以比较便利的现原实现一些简单的数据同步,比如计数器等等。并发编程包中concurrent包下的现原atomic提供我们这么一种轻量级的数据同步的选择。

使用例子

import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicInteger; public class App {     public static void main(String[] args) throws Exception {         CountDownLatch countDownLatch = new CountDownLatch(100);         AtomicInteger atomicInteger = new AtomicInteger(0);         for (int i = 0; i < 100; i++) {             new Thread() {                 @Override                 public void run() {                     atomicInteger.getAndIncrement();                     countDownLatch.countDown();                 }             }.start();         }         countDownLatch.await();         System.out.println(atomicInteger.get());     } } 

在以上代码中,并发编程包中使用AtomicInteger声明了一个全局变量,并且在多线程中进行自增,代码中并没有进行显示的加锁。服务器租用

以上代码的输出结果,永远都是100。如果将AtomicInteger换成Integer,打印结果基本都是小于100。

也就说明AtomicInteger声明的变量,在多线程场景中的自增操作是可以保证线程安全的。接下来我们分析下其原理。

原理

我们可以看一下AtomicInteger的代码

他的值是存在一个volatile的int里面。volatile只能保证这个变量的可见性。不能保证他的原子性。

可以看看getAndIncrement这个类似i++的函数,可以发现,是调用了UnSafe中的getAndAddInt。

UnSafe是何方神圣?UnSafe提供了java可以直接操作底层的能力。

进一步,网站模板我们可以发现实现方式:

如何保证原子性:自旋 + CAS(乐观锁)。在这个过程中,通过compareAndSwapInt比较更新value值,如果更新失败,重新获取旧值,然后更新。

优缺点

CAS相对于其他锁,不会进行内核态操作,有着一些性能的提升。但同时引入自旋,当锁竞争较大的时候,自旋次数会增多。cpu资源会消耗很高。

换句话说,CAS+自旋适合使用在低并发有同步数据的应用场景。

Java 8做出的改进和努力

在Java 8中引入了4个新的计数器类型,LongAdder、LongAccumulator、DoubleAdder、DoubleAccumulator。他们都是继承于Striped64。

在LongAdder 与AtomicLong有什么区别?

Atomic*遇到的问题是,只能运用于低并发场景。因此LongAddr在这基础上引入了分段锁的概念。站群服务器可以参考《JDK8系列之LongAdder解析》一起看看做了什么。

大概就是当竞争不激烈的时候,所有线程都是通过CAS对同一个变量(Base)进行修改,当竞争激烈的时候,会将根据当前线程哈希到对于Cell上进行修改(多段锁)。

可以看到大概实现原理是:通过CAS乐观锁保证原子性,通过自旋保证当次修改的最终修改成功,通过降低锁粒度(多段锁)增加并发性能。

【本文是专栏作者Hollis的原创文章,作者微信公众号Hollis(ID:hollischuang)】

戳这里,看该作者更多好文

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 戴尔电脑开机43错误(探究戴尔电脑开机43错误的根源,提供解决方案)

    戴尔电脑开机43错误(探究戴尔电脑开机43错误的根源,提供解决方案)

    2025-11-05 07:33

  • 轻松安装系统(详细步骤图文指导,实现快速安装系统)

    轻松安装系统(详细步骤图文指导,实现快速安装系统)

    2025-11-05 06:33

  • 华为G750-T01荣耀3X畅玩版手机评测(华为G750-T01荣耀3X畅玩版手机性能、摄影、续航等方面的全面评价)

    华为G750-T01荣耀3X畅玩版手机评测(华为G750-T01荣耀3X畅玩版手机性能、摄影、续航等方面的全面评价)

    2025-11-05 06:26

  • 华硕飞行堡垒8装机教程(详细指导及注意事项,助您顺利完成华硕飞行堡垒8的组装)

    华硕飞行堡垒8装机教程(详细指导及注意事项,助您顺利完成华硕飞行堡垒8的组装)

    2025-11-05 06:24

网友点评