Java中Atomic类的使用分析
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类的使用分析的更多相关文章
- Java中Object类hashCode的底层实现
Java中Object类hashCode的底层实现 openjdk\jdk\src\share\native\java\lang\Object.c 42 static JNINativeMethod ...
- 基础知识(05) -- Java中的类
Java中的类 1.类的概念 2.类中的封装 3.对象的三大特征 4.对象状态 5.类与类之间的关系 ------------------------------------------------- ...
- JAVA中的类和接口
1.类: 类是具有相同属性和方法的一组对象的集合,它为属于该类的所有对象提供了统一的抽象描述,其内部包括属性和方法两个主要部分.在面向对象的编程语言中,类是一个独立的程序单位,它应该有一个类名并包括属 ...
- java中Color类的简单总结
java中Color类的简单总结 1.颜色的常识 任何颜色都是由三原色组成(RGB),JAVA中支持224为彩色,即红绿蓝分量取值 介于0-255之间(8位表示) 2.Color类中的常量 publi ...
- Java中String类的方法及说明
String : 字符串类型 一. String sc_sub = new String(c,3,2); // String sb_copy = new String(sb) ...
- java中的类和对象
Java中的类是一个模板,它用于描述一类对象的行为和状态. 对象则是类中的一个实例,对象有状态(属性)和行为(方法).例如一条狗就是一个对象,他的状态就是他的颜色,名字,品种:他的行为就是叫,摇尾巴, ...
- java中String类学习
java中String类的相关操作如下: (1)初始化:例如,String s = “abc”; (2)length:返回字符串的长度. (3)charAT:字符操作,按照索引值获得字符串中的指定字符 ...
- 【JAVA零基础入门系列】Day11 Java中的类和对象
今天要说的是Java中两个非常重要的概念--类和对象. 什么是类,什么又是对象呢?类是对特定集合的概括描述,比如,人,这个类,外观特征上,有名字,有年龄,能说话,能吃饭等等,这是我们作为人类的相同特征 ...
- 在java中String类为什么要设计成final
在java中String类为什么要设计成final? - 胖胖的回答 - 知乎 https://www.zhihu.com/question/31345592/answer/114126087
随机推荐
- Linux防火墙的相关资料
1.查看防火墙状态 [root@localhost ~]# service iptables status 2.编辑/etc/sysconfig/iptables文件.我们实例中要打开8080端口和9 ...
- Java 异常规范
1. 只针对异常情况使用异常,不要用异常来控制流程 try { int i = 0; while (true) { range[i++].doSomething(); } } catch (Array ...
- css重点知识和bug解决方法
1.图片向下撑大3像素问题 在一个盒子里面放一张图片,默认情况下,图片会向下撑大3像素,有以下几种解决方法: 1.1 给图片添加display:block: 1.2 给图片添加 float:left: ...
- Support URL
如您有任何疑问或者建议,请通过以下方式与我们取得联系,我们会尽快响应您的反馈: 邮箱:eighteyes_cn@163.com
- 拖动条(SeekBar)的功能与用法
拖动条和进度条非常相似,只是进度条采用颜色填充来表明进度完成的程度,而拖动条则通过滑块的位置来标识数值——而且拖动条允许用户拖动滑块来改变值,因此拖动条通常用于对系统的某种数值进行调节,比如调节音量等 ...
- Vue自定义指令使用场景
当你第一次接触vue的时候,一定会使用到其中的几个指令,比如:v-if.v-for.v-bind...这些都是vue为我们写好的,用起来相当的爽.如果有些场景不满足,需要我们自己去自定义,那要怎么办呢 ...
- sqlalchemy 执行原生sql语句
from contextlib import contextmanager from sqlalchemy import create_engine, ForeignKey from sqlalche ...
- js-05-对象(object)
一.访问对象属性的两种方法 a:objectName.PropertyName 对象名.属性名 b:objectName["PropertyName"] 对象名[“ ...
- packstack-ironic
安装openstack Pike版本, 其它版本安装方法类似. centos7.6 packstack目前对NetworkManager 还不支持,我们修改下配置: systemctl disable ...
- shell编程之case分支语句
shell编程之case分支语句 case分支语句和if的多分支语句很相似. if多分支语句一般用在有(区间范围)的地方 :例如:0-100之间. if需要判断多个不同的条件. case的分支语句用在 ...