Java并发之原子变量及CAS算法-上篇
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算法
原子变量 原子变量保证了该变量的所有操作都是原子的,不会因为多线程的同时访问而导致脏数据的读取问题 Java给我们提供了以下几种原子类型: AtomicInteger和Ato ...
- 三、原子变量与CAS算法
原子变量:jdk1.5 后 java.util.concurrent.atomic 包下提供了常用的原子变量: - AtomicBoolean - AtomicInteger - AtomicLong ...
- 原子变量与CAS算法
原子变量 为了引出原子变量这个概念,我们先看一个例子. package com.ccfdod.juc; public class TestAtomicDemo { public static void ...
- 原子变量与CAS算法小结
CAS算法 CAS(compare-and-swap)是一种硬件对并发的支持,针对多处理器操作而设计的处理器中的一种特殊指令,用于管理对共享数据的并发访问. CAS是一种无锁非阻塞算法的实现. CAS ...
- volatile关键字与内存可见性&原子变量与CAS算法
1 .volatile 关键字:当多个线程进行操作共享数据时, 可以保证内存中的数据可见 2 .原子变量:jdk1.5后java.util.concurrent.atomic 包下提供常用的原子变量 ...
- Java并发之原子变量和原子引用与volatile
我们知道在并发编程中,多个线程共享某个变量或者对象时,必须要进行同步.同步的包含两层作用:1)互斥访问(原子性):2)可见性:也就是多个线程对共享的变量互斥地访问,同时线程对共享变量的修改必须对其他线 ...
- 原子变量与CAS算法(二)
一.锁机制存在的问题 (1)在多线程竞争下,加锁.释放锁会导致比较多的上下文切换和调度延时,引起性能问题. (2)一个线程持有锁会导致其它所有需要此锁的线程挂起. (3)如果一个优先级高的线程等待一个 ...
- Java编程的逻辑 (70) - 原子变量和CAS
本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http: ...
- java并发编程学习: 原子变量(CAS)
先上一段代码: package test; public class Program { public static int i = 0; private static class Next exte ...
- 计算机程序的思维逻辑 (70) - 原子变量和CAS
从本节开始,我们探讨Java并发工具包java.util.concurrent中的内容,本节先介绍最基本的原子变量及其背后的原理和思维. 原子变量 什么是原子变量?为什么需要它们呢? 在理解synch ...
随机推荐
- Avalonia应用在基于Linux的国产操作deepin上运行
deepin系统介绍 deepin(原名Linux Deepin)致力于为全球用户提供美观易用,安全可靠的 Linux发行版.deepin项目于2008年发起,并在2009年发布了以 linux de ...
- 韦东山freeRTOS系列教程之【第九章】任务通知(Task Notifications)
目录 系列教程总目录 概述 9.1 任务通知的特性 9.1.1 优势及限制 9.1.2 通知状态和通知值 9.2 任务通知的使用 9.2.1 两类函数 9.2.2 xTaskNotifyGive/ul ...
- MFC CFileDialog DoModal()无法弹出窗口,直接返回IDCANCEL
最近需要用VS2017在MFC中加一个文件浏览窗口,采用了如下方式 1 CFileDialog Dlg(TRUE); 2 int res = Dlg.DoModal(); 3 if(res == ID ...
- Java获取客户端请求信息
客户端工具类 /** * 客户端工具类 * * @author hviger */ public class ServletUtils { /** * 获取String参数 */ public sta ...
- Swift开发基础07-内存布局
了解Swift的内存布局和底层原理对于编写高性能和内存高效的应用非常重要.接下来,我将更详细地介绍Swift的内存管理机制和一些底层实现细节,包括内存布局.ARC(自动引用计数).引用类型和值类型的区 ...
- nacos:关于注册服务与配置管理
为什么要用nacos做配置中心? 1.nacos可以做到统一管理,而且在修改时可以做到动态管理,无需重启即可生效. 2.nacos通过namespace进行环境隔离, 约定: namespace:用于 ...
- 【Vue】可编辑表格与三级联动下拉
需求是给员工分配岗位,设计上是一人多岗的存在... 单位 -- 部门 -- 岗位 这样的层级 功能效果: 因为员工可以在不同的单位下任职岗位,所以这个每一个岗位都是一个独立 查询单位列表是固定的,但是 ...
- 【JDBC】Extra01 Oracle-JDBC
关于驱动包依赖: 官网提供的地址: https://www.oracle.com/database/technologies/jdbc-drivers-12c-downloads.html Maven ...
- nvidia公司官方迁移学习套件 —— NVIDIA TAO Toolkit
资料: https://blogs.nvidia.com/blog/what-is-transfer-learning/ 相关: https://developer.nvidia.com/tao-to ...
- 全球最大开源模型Grok-1 —— 马斯克 —— 自然语言大模型
当前世界上参数最大的开源大语言模型Grok-1,参数权重大小为296GB,即3140亿参数,远远超过了OpenAI的GPT-3.5模型. 该模型采用的3140亿参数的MoE模型,在给定token上的激 ...