Java并发之原子变量及CAS算法-上篇

编辑

概述

本文主要讲在Java并发编程的时候,如果保证变量的原子性,在JDK提供的类中是怎么保证变量原子性的呢?。对应Java中的包是:java.util.concurrent.atomic包下。因为涉及到了CAS算法,需要对CAS算法讲解及CAS算法三个问题怎么解决以及和Synchroized比较。文章比较长,所以就分为上下两个篇幅讲解。本文是上篇《Java并发之原子变量及CAS算法-上篇》

本文是《凯哥分享Java并发编程之J.U.C包讲解》系列教程中的一篇。如果想系统学习,建议从第一篇开始看。

原子变量案例

在Java中有一种写法:int i = 10; i++ 这种写法。

我们先来看看:

编辑

输入的是0还是1呢 ?

I++输出0的原因分析

答案是:0。为什么呢?凯哥把编译后的class文件反编译,咱们看:

编辑

说明:i的操作是i++;y的操作是++y.

从反编译后的代码,我们可以看到i++在JVM中的操作,总共分三步:

第一步:声明变量var10000 ,然后将i赋值给var10000,此时var10000的值是0;

第二步:声明变量var3 然后把i+1 赋值给var3,此时,var3的值等于1了;

第三步:将变量var10000的值又赋值给了i,此时因为var10000的值是0,所以i的值也是0

所以在sysout(i)的时候,就输出了0.

我们分析上面1,2,3步骤,可以发现。其实i++执行的是:读取-修改-重写 三个操作。

既然读写操作,就会涉及到变量原子性。测试在多线程下变量原子性

测试多线程下的变量原子性

那么,如果我们把对i的操作放到多个线程中操作结果会是什么样的呢?

线程操作I的代码:

编辑

开启十个线程同时操作i的代码:

编辑

我们来看看运行结果:

编辑

从运行结果中,我们可以看到,线程Thread-5和线程Thread-8的值是一样的。

根据上面运行的场景,我们发现,变量i其实是十个线程中的共享变量。从运行的结果来看,多个线程操作后,结果出问题了。

不同线程在内存中运行模拟图:

编辑

线程1;线程2;以及主线程之间运行关系,可以详见凯哥上一篇文章:《Java并发之内存可见性问题怎么解决》。这篇文章详细讲解了怎么关系。

已经看过凯哥上一篇文章或者是知道volatile关键字的朋友可能要说,这不就是线程之间变量可见性问题嘛。使用volatile关键字修饰i就可以了。真的可以了吗?

我们修改程序,用volatile来修饰,看看运行结果:

使用volatile关键字是否能解决多线程情况下变量原子性呢?

用volatile来修饰变量:

private volatile int shardData = 0;

运行结果:

编辑

我们发现,就算使用volatile关键字修饰了,依然存在多线程下变量原子性的问题。

怎么解决这种并发下变量原子性问题呢?

Java的atomic包

在jdk1.5以后,Java为我们提供了一个常用的原子变量。都在:java.util.concureent.atomic包下。我们来看看,都有哪些:

编辑

编辑

编辑

从JDK的API文档中(凯哥使用的是JDK1.8的API)我们可以看到常用的原子性变量。

怎么保证原子性呢?

那么,在atomic包下的这些类怎么保证原子性呢?

1:该包下的变量都是使用volatile关键字来修饰。

解决了多线程之间变量可见性。

Int类型的原子性对象AtomicInteger对象中:

编辑

用于对象的AtomicReference对象中:

编辑

都是使用volat关键字修饰的。

2:使用CAS算法

保持了变量的原子性

总结:

在Java的JDK中提供了concurrent.atomic包,使用这个包下的对象创建的变量就能保证原子性。

保证原子性的策略:

1:变量都是用Volatile关键字修饰。来保证内存可见性

2:使用CAS算法,来保证原子性。

编辑

下篇预告:

在下一篇文章中,我们主要讲解CAS算法原理及CAS算法会参数哪些问题(三个问题)?JDK是怎么解决的?修改i++使其成为具有原子性变量怎么实现。

java cas原理_Java并发之原子变量及CAS算法-上篇相关推荐

  1. java aqs原理_Java并发之AQS详解

    一.概述 谈到并发,不得不谈ReentrantLock:而谈到ReentrantLock,不得不谈AbstractQueuedSynchronized(AQS)! 类如其名,抽象的队列式的同步器,AQ ...

  2. java cas并发_java并发之CAS

    写在最前面 在上文java并发之volatile末尾有提到,volatile并不能保证++操作的线程安全.我们来通过一个简单的例子看下为什么. ++测试demo 通过javap -v看下其反编译后字节 ...

  3. java锁原理_Java锁原理学习

    Java锁原理学习 为了学习Java锁的原理,参照ReentrantLock实现了自己的可重入锁,代码如下: 先上AQS的相关方法: // AQS = AbstractQueuedSynchroniz ...

  4. java 如何测试_java – 如何测试一个变量是否设置?

    Java编译器不会让您定义变量并在赋值之前使用它们,因此问题不存在于与php中存在的相同的形式. 编辑 如果在你的情况下,编译器并没有阻止你(因为这是一个实例变量),最好的解决方案可能是将变量初始化为 ...

  5. java volatile 死锁_Java 多线程:volatile 变量、happens-before 关系及内存一致性

    原标题:Java 多线程:volatile 变量.happens-before 关系及内存一致性 来源:ImportNew - paddx 更新 请参考来自 Jean-philippe Bempel ...

  6. java map原理_Java HashMap底层原理分析

    前两天面试的时候,被面试官问到HashMap底层原理,之前只会用,底层实现完全没看过,这两天补了补功课,写篇文章记录一下,好记性不如烂笔头啊,毕竟这年头脑子它记不住东西了哈哈哈.好了,言归正传,今天我 ...

  7. java性别数据类型_Java基础-数据类型及变量

    Java基本语法 1.标识符(zhi) 含义:名字 类名.对象名.方法名.变量名.常量名-- 一个合法的标识符的组成:数字.字母._和$ 注意事项: 不能重复 不能以数字开头 区分大小写 不能以关键字 ...

  8. java断点续传原理_java 文件断点续传实现原理

    关键字: RandomAccessFile 一.作用: 随机流(RandomAccessFile)不属于IO流,支持对文件的读取和写入随机访问. 二.随机访问文件原理: 首先把随机访问的文件对象看作存 ...

  9. java list原理_Java集合:ArrayList的实现原理

    目录: 一. ArrayList概述: ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存. ArrayList不是线程安全的,只能用在单 ...

最新文章

  1. 使用JAX-RS创建RESTful Web Service
  2. openresty开发系列38--通过Lua+Redis 实现动态封禁IP
  3. 在gcc中定义符号常量
  4. Java中常见数据结构:list与map
  5. Java中的注解是如何工作的
  6. 摆脱冷气_摆脱匿名类
  7. 让PHP支持页面后退的两种方法
  8. [转载] 全本张广泰——第八回 广泰欲悬梁 老侠三救徒
  9. spring cloud学习笔记02
  10. 修改监视器驱动为大显示器来提高屏幕分辨率
  11. javaweb框架 一些底层实现
  12. gpgga格式读取MATLAB,gpgga数据格式
  13. 工厂信息化系统(ERP、PLM、MES、WMS)架构设计与建设规划
  14. mysql数据库修复工具 innodb表数据恢复 ibd文件恢复工具
  15. 自适应PC端网页制作使用rem
  16. L9110H电机驱动模块 Arduino 小水泵小风扇
  17. html怎么添加自动关机,电脑自动关机设置方法大全
  18. 计算机导航辅助教程,计算机导航辅助技术带给骨肿瘤外科医生的思考
  19. 俄勒冈健康与科学大学计算机,俄勒冈健康与科学大学费用
  20. 调用bing图片html代码,网站背景调用必应Bing每日图片教程附接口

热门文章

  1. linux 发送http请求方式
  2. 编写一个函数,该函数能判断一个英文句子str(带空格)中是否含有某个单词w,如“How old are you?”含有“old”。在main函数中输入一个英文句子,再输入一个单词,如果英文句子中含有那
  3. 计算机如何玩二十四点游戏,数学二十四点游戏有什么技巧吗?
  4. 第二次想上传demo到github
  5. BugkuCTF-WEB题秋名山车
  6. 微观经济学如何计算机会成本,【微观经济学】机会成本
  7. java 获取类方法_Java之反射机制三:获取类的方法
  8. android 自定义progressbar demo,Android 自定义进度条ColorfulProgressbar,原理简单、效果还行...
  9. 怎么知道自己是否适合计算机专业,事实:我怎么知道我的旧计算机是否适合win7或win10?...
  10. java是值传递还是引用传递_Java 到底是值传递还是引用传递?