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

这是一篇来自粉丝的投稿,作者【林湾村龙猫】最近在阅读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() {@Overridepublic 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乐观锁保证原子性,通过自旋保证当次修改的最终修改成功,通过降低锁粒度(多段锁)增加并发性能。

Java并发编程包中atomic的实现原理相关推荐

  1. Java并发编程(中下篇)从入门到深入 超详细笔记

    接上一篇博客笔记:Java并发编程(中上篇)从入门到深入 超详细笔记_未来很长,别只看眼前的博客-CSDN博客https://blog.csdn.net/weixin_53142722/article ...

  2. Java 并发编程——Executor框架和线程池原理

    Java 并发编程系列文章 Java 并发基础--线程安全性 Java 并发编程--Callable+Future+FutureTask java 并发编程--Thread 源码重新学习 java并发 ...

  3. Java 并发编程CAS、volatile、synchronized原理详解

    CAS(CompareAndSwap) 什么是CAS? 在Java中调用的是Unsafe的如下方法来CAS修改对象int属性的值(借助C来调用CPU底层指令实现的): /*** * @param o ...

  4. Java并发编程(多线程)中的相关概念

    众所周知,在Java的知识体系中,并发编程是非常重要的一环,也是面试中必问的题,一个好的Java程序员是必须对并发编程这块有所了解的. 并发必须知道的概念 在深入学习并发编程之前,我们需要了解几个基本 ...

  5. Java并发编程 synchronized保证线程安全的原理

    文章转载致博客 blog.csdn.net/javazejian/- 自己稍加完善. 线程安全是并发编程中的重要关注点,应该注意到的是,造成线程安全问题的主要诱因有两点,一是存在共享数据(也称临界资源 ...

  6. Java并发编程的基础-线程的终止原理

    我们来看一下 thread.interrupt()方法做了什么事情 这个方法里面,调用了interrupt0(),这个方法在前面分析start方法的时候见过,是一个native方法,这里就不再重复贴代 ...

  7. Java并发编程,无锁CAS与Unsafe类及其并发包Atomic

    为什么80%的码农都做不了架构师?>>>    我们曾经详谈过有锁并发的典型代表synchronized关键字,通过该关键字可以控制并发执行过程中有且只有一个线程可以访问共享资源,其 ...

  8. Java并发编程—常见面试题

    建议: 学习java并发前需要先掌握JVM知识 关于下面问题档案的详细解析都在后面推荐的相关系列文章中 一.线程安全相关 1.什么叫线程安全? 线程安全就是说多线程访问同一代码,不会产生不确定的结果. ...

  9. java并发编程实践_Java并发编程实践如何正确使用Unsafe

    一.前言 Java 并发编程实践中的话: 编写正确的程序并不容易,而编写正常的并发程序就更难了.相比于顺序执行的情况,多线程的线程安全问题是微妙而且出乎意料的,因为在没有进行适当同步的情况下多线程中各 ...

最新文章

  1. oracle导出表格式csv,Oracle数据库文件导出为CSV格式的方法
  2. InnoDB Monitors
  3. android webview 加载进度和自定义404错误页面
  4. 如何在Vmware-Workstation中配置两块网卡?
  5. 衡量发动机性能的重要指标—升功率
  6. 腾讯云加入自媒体分享计划可以免费领取.cn域名啦
  7. C#中的多线程 - 并行编程 z
  8. 整数反转Java_详解 LeetCode_007_整数反转(Java 实现)
  9. 小D课堂 - 新版本微服务springcloud+Docker教程_3-03CAP原理、常见面试题
  10. Atitit 并发技术的选项 attilax总结 艾龙 著 1. 三大并发模型 1 2. 从可读性考虑 优先使用 并行工作者 多线程模式,不要使用异步流水线模式 2 2.1. 多线程模式方便全局
  11. 无法解析的外部符号 __imp_RegCloseKey
  12. PFC2D学习笔记——柔性簇(cluster)生成
  13. Online Judge系统大全
  14. CTF线下AWD攻防步骤总结
  15. 数据采集卡采样率M Sa/s 与G Sa/s是什么意思
  16. python列表元素按条件分组_Python列表元素分组
  17. 【STM32学习笔记】(9)——串口通讯(USART)详解
  18. 【数据分析】基于matlab GUI学生成绩管理系统【含Matlab源码 1981期】
  19. MT管理器和高级终端Termux
  20. ChunkedEncodingError: ('Connection broken: IncompleteRead(0 bytes read)', IncompleteRead(0 bytes rea

热门文章

  1. leetcode145. 二叉树的后序遍历
  2. leetcode239. 滑动窗口最大值(思路+详解)
  3. android环境搭建出错,androidstudio配置环境遇到的各种错误(持续更新中)
  4. vue.js中mock本地json数据
  5. Java HashMap的实现原理详解
  6. Deep Boltzmann Machines
  7. 分布式缓存——一致性哈希算法
  8. 2019-03-18-算法-进化(反转链表)
  9. 序列计数(动态规划/自动机/前缀和优化)
  10. 【LOJ#6682】梦中的数论(min_25筛)