1:为什么会出现Atomic类

  在多线程或者并发环境中,我们常常会遇到这种情况 int i=0; i++ 稍有经验的同学都知道这种写法是线程不安全的。为了达到线程安全的目的,我们通常会用synchronized来修饰对应的代码块。现在我们有了新的方法,就是使用J.U.C包下的atomic类。

2:Atomic类的原理是什么呢

  一句话来说,atomic类是通过自旋CAS操作volatile变量实现的。

  CAS是compare and swap的缩写,即比较后(比较内存中的旧值与预期值)交换(将旧值替换成预期值)。它是sun.misc包下Unsafe类提供的功能,需要底层硬件指令集的支撑。

  使用volatile变量是为了多个线程间变量的值能及时同步。

3:为什么使用Atomic类

  按理来说,使用synchroized已经能满足功能需求了。为什么还会有这个类呢?那肯定是性能的问题了。

  在JDK1.6之前,synchroized是重量级锁,即操作被锁的变量前就对对象加锁,不管此对象会不会产生资源竞争。这属于悲观锁的一种实现方式。

  而CAS会比较内存中对象和当前对象的值是否相同,相同的话才会更新内存中的值,不同的话便会返回失败。这是乐观锁的一中实现方式。这种方式就避免了直接使用内核状态的重量级锁。

  但是在JDK1.6以后,synchronized进行了优化,引入了偏向锁,轻量级锁,其中也采用了CAS这种思想,效率有了很大的提升。

4:Atomic类的缺点

  ABA问题:

    对于一个旧的变量值A,线程2将A的值改成B又改成可A,此时线程1通过CAS看到A并没有变化,但实际A已经发生了变化,这就是ABA问题。解决这个问题的方法很简单,记录一下变量的版本就可以了,在变量的值发生变化时对应的版本也做出相应的变化,然后CAS操作时比较一下版本就知道变量有没有发生变化。atomic包下AtomicStampedReference类实现了这种思路。Mysql中Innodb的多版本并发锁也是这个原理。

  自旋问题:

    atomic类会多次尝试CAS操作直至成功或失败,这个过程叫做自旋。通过自旋的过程我们可以看出自旋操作不会将线程挂起,从而避免了内核线程切换,但是自旋的过程也可以看做CPU死循环,会一直占用CPU资源。这种情形在单CPU的机器上是不能容忍的,因此自旋一般都会有个次数限制,即超过这个次数后线程就会放弃时间片,等待下次机会。因此自旋操作在资源竞争不激烈的情况下确实能提高效率,但是在资源竞争特别激烈的场景中,CAS操作会的失败率就会大大提高,这时使用中重量级锁的效率可能会更高。当前,也可以使用LongAdder类来替换,它则采用了分段锁的思想来解决并发竞争的问题。

Java中Atomic类的使用分析的更多相关文章

  1. Java中Object类hashCode的底层实现

    Java中Object类hashCode的底层实现 openjdk\jdk\src\share\native\java\lang\Object.c 42 static JNINativeMethod ...

  2. 基础知识(05) -- Java中的类

    Java中的类 1.类的概念 2.类中的封装 3.对象的三大特征 4.对象状态 5.类与类之间的关系 ------------------------------------------------- ...

  3. JAVA中的类和接口

    1.类: 类是具有相同属性和方法的一组对象的集合,它为属于该类的所有对象提供了统一的抽象描述,其内部包括属性和方法两个主要部分.在面向对象的编程语言中,类是一个独立的程序单位,它应该有一个类名并包括属 ...

  4. java中Color类的简单总结

    java中Color类的简单总结 1.颜色的常识 任何颜色都是由三原色组成(RGB),JAVA中支持224为彩色,即红绿蓝分量取值 介于0-255之间(8位表示) 2.Color类中的常量 publi ...

  5. Java中String类的方法及说明

    String : 字符串类型 一.      String sc_sub = new String(c,3,2);    //      String sb_copy = new String(sb) ...

  6. java中的类和对象

    Java中的类是一个模板,它用于描述一类对象的行为和状态. 对象则是类中的一个实例,对象有状态(属性)和行为(方法).例如一条狗就是一个对象,他的状态就是他的颜色,名字,品种:他的行为就是叫,摇尾巴, ...

  7. java中String类学习

    java中String类的相关操作如下: (1)初始化:例如,String s = “abc”; (2)length:返回字符串的长度. (3)charAT:字符操作,按照索引值获得字符串中的指定字符 ...

  8. 【JAVA零基础入门系列】Day11 Java中的类和对象

    今天要说的是Java中两个非常重要的概念--类和对象. 什么是类,什么又是对象呢?类是对特定集合的概括描述,比如,人,这个类,外观特征上,有名字,有年龄,能说话,能吃饭等等,这是我们作为人类的相同特征 ...

  9. 在java中String类为什么要设计成final

    在java中String类为什么要设计成final? - 胖胖的回答 - 知乎 https://www.zhihu.com/question/31345592/answer/114126087

随机推荐

  1. QT使用mysql

    1.首先要下载qt create 官网链接:https://wiki.qt.io/Main 2.下载mysql驱动mysql-connector-c,注意是c或c++版本的驱动 官网下载地址:http ...

  2. DOM事件流的三个阶段

    事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流. DOM事件流分为三个阶段,分别为: 捕获阶段:事件从Document节点自上而下向目标节点传播的阶段: 目标阶段:真正的目标 ...

  3. DG重启之后主备数据不同步

    问题描述:本来配置好的DG第二天重启之后,发现主备库数据不能同步,在主库上执行日志切换以及创建表操作都传不到备库上,造成这种错误的原因是主库实例断掉后造成备库日志与主库无法实时接收 主库:orcl  ...

  4. 安装Android Studio (一)同时配置Android Studio环境变量

    安装Android Studio 安装android 一直next就行了.这以步需要10分钟左右. 我的安卓SDK在这个目录 C:\Users\user\AppData\Local\Android\s ...

  5. C++ std::deque 基本用法

    #include <iostream> #include <string> #include <deque> // https://zh.cppreference. ...

  6. Mysql、ES 数据同步

    数据同步中间件 不足:不支持 ES6.X 以上.Mysql 8.X 以上 ime 标识最大时间 logstash全量.增量同步解决方案 https://www.elastic.co/cn/downlo ...

  7. Spring Security OAuth2 开发指南(非最新版本)

    请注意哈,本文翻译的时候,官网的的版本和本文翻译的时候是一一对应的. 但是官网已经更新文档和概念了,因此和本文翻译的就不在是同一个范围了. 因此我已经将标题修改为(非最新版本),各位老铁直接看官网就可 ...

  8. Prism_Composite Commands(3)

    Composite Commands 在许多情况下,视图模型定义的命令将绑定到关联视图中的控件,以便用户可以直接从视图中调用该命令.但是,在某些情况下,您可能希望能够从应用程序UI的父视图中的控件调用 ...

  9. 新建GitHub仓库与删除

    一.登录GitHub创建仓库 ,步骤如下: 1.点击新建 2.填写仓库名称等 3.创建完成 二.关联已有的本地项目(没有需要关联的本地项目,可以直接从刚刚创建的GitHub仓库clone) 1.到本地 ...

  10. ASP.NET MVC快速开发框架FastExecutor开发全过程感受及总结

    困境 追溯到2018年5月份,是个炎热的夏天,毕业后1年7个月我提出了离职,原因是受不了原来公司过度的封装框架感觉一年多毫无进步与实施天天轰炸般的电话,偶然间出去面试了一次发现自己知识真的是比较局限, ...