1. 原子操作类的作用

当程序更新一个变量时,如果多个线程同时更新该变量,可能会得到期望以外的值。比如i=1, 线程A更新i+1, 同时线程B更新I+1,经过两个线程的操作,最终变量i的值可能不是3,而是2。因为线程A、B拿到的i的值都是1,这就是线程不安全的更新操作。我们可以用synchronized来解决这样的问题,synchronized可以保证多线程之间的同步,以保证多个线程不会同时操作变量i。

但是在JDK1.5开始,就提供了java.util.concurrent.atomic包,这个包中的原子操作类提供了更为简单高效、线程安全的方式来更新一个变量的值。

2. 原子操作类基本分类

原子更新基本类型(3个)

AtomicBoolean 原子更新布尔类型

AtomicInteger 原子更新整型

AtomicLong 原子更新长整型

原子更新数组(3个)

AtomicIntegerArray 原子更新整形数组中的元素

AtomicLongArray 原子更新长整型数组中的元素

AtomicReferenceArray 原子更新引用类型数组中的元素

原子更新引用类型(3个)

AtomicReference 原子更新引用类型

AtomicReferenceFieldUpdater 原子更新引用类型中的字段

AtomicMarkableReference 原子更新带有标记位的引用类型

原子更新字段类(3个)

AtomicIntegerFieldUpdater 原子更新整形字段

AtomicLongFieldUpdater 原子更新长整型字段

AtomicStampedReference 原子更新带有版本号的引用类型

3. CAS方式实现原子操作基本原理

JVM中CAS操作主要是利用了处理器提供的CMPXCHG执行实现。基本的思路就是利用循环进行CAS操作,直到成功为止。CAS主要涉及到三个操作数,内存中的值(V)、旧的预期值(A)、需要修改的新值(B),当且仅当V==A时,才会将V值修改为B值,否则什么都不做,并且通过一个布尔值返回结果。伪代码如下:

//伪代码

boolean compareAndSwap(V,A,B){

for(;;){

if(V==A)

V=B;//替换旧值

}

}

4. CAS方式产生的问题(3个)

ABA问题: CAS操作时,检查值有没有变化,如果没有变化则更新,但是如果一个值原来是A,中间变成了B,然后又变为A,CAS进行检查时,就会发现它的值没有变化,但是实际上却已经变化了。解决ABA问题,可以在变量前加一个版本号,变量更新时,版本号就加1.

循环时间长,开销大:CAS采用的是自循的方式进行检查,如果长时间不成功,那么就会给CPU带来非常大的开销。

只能保证一个共享变量的原子操作:当对一个共享变量进行原子操作时,我们可以采用CAS的方式进行更新,但是如果对多个共享变量进行操作时,CAS就无法保证操作的原子性,那么这个时候就需要用锁来实现。

5. 原子操作类中主要的方法

boolean compareAndSet(int expect, int update) ;如果输入的值等于预期值,那么以原子的方式将该值设为输入的值。

int addAndGet(int delta);以原子的方式将输入的数值与实例中的值相加,并返回更新之后的值

int getAndAdd(int delta); 以原子的方式将输入的数值与实例中的值相加,并返回旧值

int getAndSet(int newValue);以原子方式设置为newValue的值,并返回旧值

通过阅读源码,可以发现CAS操作都是使用Unsafe类下的方法进行操作,而Unsafe类只提供了三种CAS方法:

compareAndSwapObject(this, valueOffset, expect, update);

compareAndSwapLong(this, valueOffset, expect, update);

compareAndSwapInt(this, valueOffset, expect, update);

所以,对于其他类型的原子操作,都是进行类型转换,将其类型转换为这三种类型,然后进行原子操作。如Boolean型的,先转成整整,然后在使用compareAndSwapInt进行操作;所以像char/float/double/short...等都可以按照这种思路实现。

java中的原子操作_[Java并发系列] 2.Java中的原子操作类相关推荐

  1. java雪崩_【并发编程】java 如何解决redis缓存穿透、缓存雪崩(高性能示例代码)...

    [并发编程]java 如何解决redis缓存穿透.缓存雪崩(高性能示例代码) 发布时间:2018-11-22 16:48, 浏览次数:872 , 标签: java redis <>缓存穿透 ...

  2. java底层原理书籍_阿里面试题:Java中this和super关键字的底层实现原理

    知道的越多,不知道的就越多,业余的像一棵小草! 编辑:业余草 来源:https://www.xttblog.com/?p=5028 B 站:业余草 最近一个粉丝加我说,接到了阿里的面试,问问我阿里会面 ...

  3. java阻塞队列作用_简单理解阻塞队列(BlockingQueue)中的take/put方法以及Condition存在的作用...

    简单理解阻塞队列(BlockingQueue)中的take/put方法以及Condition存在的作用 Condition:可以理解成一把锁的一个钥匙,它既可以解锁(通知放行),又可以加锁(阻塞) n ...

  4. java io流操作_十个Demo进行讲解Java中IO流的常用操作~

    好久不见的IO流 对IO流的学习,我记得还是初学Java基础的时候,后来找工作过程中经常看到有些招聘信息中写到熟悉IO流,现在想想IO流,真的是一脸懵逼,不说这么多废话了,IO流这次好好整理一下. 说 ...

  5. java 格式化 布尔型_这么久才知道Java中的format很强大!

    Java中允许我们对指定的对象进行某种格式化,从而得到我们想要的格式化样式. Format 首先介绍java.text包中的Format Foramt是一个抽象基类,其具体子类必须实现 format( ...

  6. java中的多态性_[转载] c++多态与java多态性_Java中的多态性

    参考链接: Java中的加法和串联 c++多态与java多态性 Polymorphism is one of the core concepts of OOPS paradigm. The meani ...

  7. java 图片识别提取_老司机帮您Java 提取/读取PDF中的图片

    电脑现已成为我们工作.生活和娱乐必不可少的工具了,在使用电脑的过程中,可能会遇到Java 提取/读取PDF中的图片的问题,如果我们遇到了Java 提取/读取PDF中的图片的情况,该怎么处理怎么才能解决 ...

  8. java excel 列数_计算Excel工作表列中的行数(提供的Java代码)

    在参考我之前的问题How to calculate number of rows in a column of Excel document using Java时,我能够计算给定表格中的总列数.现在 ...

  9. java正则匹配公司名称_【已解决】Java的正则表达式java.util.regex中的命名的组(named group)...

    [问题] 在折腾: 的过程中,需要用到命名的组,另外还用到替换中的引用命名的组. 想要搞懂如何使用. [解决过程] 1. 最开始是参考,官网手册: 中,并没有看到,如何使用命名的组. 2.参考: 得知 ...

  10. java 内存模型 多线程_Java 高并发三:Java内存模型和线程安全详解

    网上很多资料在描述Java内存模型的时候,都会介绍有一个主存,然后每个工作线程有自己的工作内存.数据在主存中会有一份,在工作内存中也有一份.工作内存和主存之间会有各种原子操作去进行同步. 下图来源于这 ...

最新文章

  1. C#学习视频分享与开发技术QQ交流群
  2. 我司用了 6 年的 Redis 分布式限流器,很牛逼了!
  3. 2016c语言模拟试卷一,2016年9月计算机二级C语言考试预测试题及答案(4)
  4. Java8 Stream Collectors groupingBy使用
  5. 牛客网多校联合训练1 J Different Integers(可持久化线段树/莫队)
  6. 【Warning】Unity2021.1将不兼容之前版本ECS
  7. window系统服务器,远程连接mysql数据库。
  8. 2017《JAVA》预备作业 计科1501班 王奕开
  9. python有道批量单词音标整理-Python 批量翻译 使用有道api;
  10. 7.详解第三代移动通信系统——WCDMA、TD-SCDMA、CDMA2000
  11. 信息安全初窥(一):聊一聊这个专业的前途
  12. 计算机发挥cpu全部,怎样提升CPU性能?怎么让CPU发挥最大的性能
  13. win10微软商店/账号登录一直转圈
  14. R语言之导入数据源(二)
  15. 网页制作 - 问卷网的首页
  16. JS实战应用之做LOL领图标任务~
  17. Testudo:Spartan + Groth16 的R1CS ZKP证明系统
  18. 百度地图API获取某个行政区
  19. ~ 如何用C++自制一个日麻游戏 ~ 概述
  20. spring配置文件中的p和c命名空间的使用

热门文章

  1. 教你如何在项目中集成推送功能
  2. 润乾V5打印完成后事务处理
  3. VINS(五)非线性优化与在线标定调整
  4. java的引用指的是什么_请问java里的引用是指什么啊?
  5. 信息学奥赛一本通(1041:奇偶数判断)
  6. 数列分块入门 1(LibreOj-6277)
  7. 数论 —— 莫比乌斯反演
  8. 小A点菜(洛谷-P1164)
  9. 津津的储蓄计划(洛谷-P1089)
  10. Spoken English-口语-练习频次