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以后,synchroized进行了优化,引入了偏向锁,轻量级锁,其中也采用了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中Atomic类的使用分析相关推荐

  1. java 枚举的继承_java中枚举类可以被继承吗?

    java 枚举类 java中,使用关键字enum来定义枚举类,枚举类是一个特殊的类,大部分功能和普通类是一样的,区别为: ● 枚举类继承了java.lang.Enum类,而不是默认的Object类.而 ...

  2. java中如何把时间封装成类,java-如何在不使用任何不推荐使用的类的情况下将日期从一种格式转换为另一种格式的日期对象?...

    java-如何在不使用任何不推荐使用的类的情况下将日期从一种格式转换为另一种格式的日期对象? 我想将date1格式的日期转换为date2格式的日期对象. SimpleDateFormat simple ...

  3. Java IO流中 File文件对象与Properties类(四)

    File类 用来将文件或目录封装成对象 方便对文件或目录信息进行处理 File对象可以作为参数传递给流进行操作 File类常用方法 创建 boolean createNewFile():创建新文件,如 ...

  4. Java中使用Observer接口和Observable类实践Observer观察者模式

    在Java中通过Observable类和Observer接口实现了观察者模式.实现Observer接口的对象是观察者,继承Observable的对象是被观察者. 1. 实现观察者模式 实现观察者模式非 ...

  5. java 向上取整_java 中的异常处理和常用类使用

    一.异常: 1.异常的简单介绍: Throwable类 / Error Exception | | Unchecked Checked Runtime Exception Exception Exce ...

  6. java floatmath_【Android】解决FloatMath类中方法在API 23以后不存在问题

    1.问题原因分析 在Android SDK更新至23以上时,我们会发现之前在某些地方因计算需要使用到的FloatMath类中的方法如FloatMath.ceil()与FloatMath.sin()等都 ...

  7. java可以使用c语言中的输入,c语言中的scanf在java中应该怎么表达,Scanner类。

    1 java是面向对象的语言 它没有像C语言中的scanf()函数,但是它的类库中有含有scanf功能的函数 2 java.util包下有Scanner类 Scanner类的功能与scanf类似 3 ...

  8. java中的复合数据类型是什么_【填空题】类是Java中的一种重要的复合数据类型,是组成Java程序的基本要素。一个类的实现包括两部分:____和_____....

    [填空题]类是Java中的一种重要的复合数据类型,是组成Java程序的基本要素.一个类的实现包括两部分:____和_____. 更多相关问题 [名词解释] 观叶树木 [单选] 开花时有浓郁香气的树种是 ...

  9. java中怎样定义实数_Java Math 类中的新功能,第 1 部分: 实数

    在这篇由两部分组成的文章中,Elliotte Rusty Harold 与您一起探讨经典 java.lang.Math 类中的"新"功能.第 1 部分主要讨论比较单调的数学函数.第 ...

  10. java中system_《java中System类》 | 学步园

    System类 System类是一个特殊类,它是一个公共最终类,不能被继承,也不能被实例化,即不能创建System类的对象.System类功能强大,与Runtime一起可以访问许多有用的系统功能.Sy ...

最新文章

  1. Nature Reviews:全新的益生元定义和范围
  2. 独家 | 使用高斯混合模型,让聚类更好更精确(附数据代码学习资源)
  3. linux缓存限制,如何限制复制使用的缓存,以便仍有其他缓存可用的内存?_linux_开发99编程知识库...
  4. [转帖]Mootools源码分析-04 -- Array
  5. Ubuntu 17.04 Chrome 安装
  6. java实现c#的datetime.ticks_java的Date.getTime()转换成C#的Datetime.ticks | 学步园
  7. python红楼梦词频统计_用 Python 分析《红楼梦》(2)-阿里云开发者社区
  8. html中basefont标签,HTML的basefont标签
  9. 超过响应缓冲区限制_Nginx如何限制并发连接数和连接请求数?
  10. TensorFlow精进之路(八):神经元
  11. 合并txt文件的几个方法
  12. php使用手册输出语句,php echo和print区别及语句用法是什么 - php完全自学手册 - php中文网手册...
  13. UNITY中帧动画的制作
  14. FPGA 视频处理 FIFO 的典型应用
  15. [iuud8]ios不同版本下推送本地通知
  16. 阻止野猪入境 丹麦在德国边境开始建设边境围栏
  17. JAVA自学-day16-List的子类、泛型、增强for循环、静态导入、可变参数
  18. 数学笔记——导数1(导数的基本概念)
  19. 使用echarts实现系统性能动态监控(数据实时展示)
  20. android edittext 输入法表情,Android开发中EditText禁止输入Emoji表情符

热门文章

  1. 如何设计出完美的动画技术架构
  2. argox打码机的pplb指令开发
  3. 新品周刊 | 昕诺飞发布飞利浦智能照明产品;AO史密斯推出新品空气净化器
  4. Android中的run-as命令引出升降权限的安全问题
  5. JDK之ZGC介绍.JAVAEE最新JDK剖析
  6. 写得很好很真实的一篇高考作文居然得了0分
  7. 【Codecs系列】视频会议中的AV1编解码器
  8. regsvr32 注册.dll的用法
  9. UEM系列(二)初识UEM“探针”技术
  10. PDF文档电子公章的初试