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

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

def57216edb1d8ef02852842c6f934fb.png

编辑

概述

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

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

原子变量案例

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

我们先来看看:

5c6f273d0d41f95393364874fcee8858.png

编辑

输入的是0还是1呢 ?

I++输出0的原因分析

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

2093ec14dc876a280bba3e1e3301edb7.png

编辑

说明: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的代码:

7c70ee81f1492c329b0606f2e36282ae.png

编辑

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

e14047d981dd9cdf94e25030865efcfe.png

编辑

我们来看看运行结果:

55be67b9b3454b230eb5f1a5ba91d5aa.png

编辑

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

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

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

7460314cd54dd534655bf2e330078f9a.png

编辑

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

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

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

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

用volatile来修饰变量:

private volatile int shardData = 0;

运行结果:

7025412811ed58472fcbb681fb34fc17.png

编辑

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

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

Java的atomic包

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

09b196cb3db2a4d339d7638f09271786.png

编辑

818e0fd24920844ddcbfba505b7661a6.png

编辑

493045f60a94b308af1774a0303b4eca.png

编辑

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

怎么保证原子性呢?

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

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

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

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

1bbaa901c3576629ef36aa41936e4998.png

编辑

用于对象的AtomicReference对象中:

e6b8af6232a8cc24ee090cdf45340653.png

编辑

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

2:使用CAS算法

保持了变量的原子性

总结:

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

保证原子性的策略:

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

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

928f920dbfb8298bd43333eaec0c4d9e.png

编辑

下篇预告:

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/533684.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

node ajax validator,使用validator.js对字符串数据进行验证

validator.js是一个对字符串进行数据验证和过滤的工具库,同时支持Node端和浏览器端,github地址是https://github.com/chriso/validator.js主要API如下:验证APIcontains(str, seed)验证str中是否含有seedequals(str, comparison)验证是否相等i…

css span 右端对齐_CSS标准文档流

web页面的制作,是个“流”,像水流一样,必须从上往下,一点点的编织,不像画画,可以这个地方画一个,另一个地方画一个,随意而为。标准文档流的一些微观现象1. 空白折叠现象1)标签与标签…

composer升级_Composer 使用姿势与 Lumen 升级指南

Composer 使用姿势这里主要说说 composer.json 和 composer.lock 文件的作用。composer.jsoncomposer.json 文件包含了项目的依赖和其它的一些元数据,使用 JSON format 编写。当初次调用 composer install 时,Composer 会根据 composer.json 文件&#x…

服务器间传文件$d,基于OpenSSH+WinSCP完成Windows服务器之间的文件传输

背景经常会遇到在不同服务器之间传输文件,Linux和Linux之间用命令rsync, windows和linux之间普遍是有图形化界面的ftp软件,老黄平时用的比较多的是FileZilla。Windows和Windows之间的话,90%都是在一台机器复制,到另一台…

dbgrideh 为什么只一行_Mysql性能优化:为什么count(*)这么慢?

导读在开发中一定会用到统计一张表的行数,比如一个交易系统,老板会让你每天生成一个报表,这些统计信息少不了sql中的count函数。但是随着记录越来越多,查询的速度会越来越慢,为什么会这样呢?Mysql内部到底是…

jmeter 高并发测试报告_JMeter分布式测试

一、为什么要使用分布式测试按照一般的压力机配置,jmeter的GUI模式下(Windows),最多支持300左右的模拟请求线程,再大的话,容易造成卡顿、无响应等情况,这是限于jmeter其本身的机制和硬件配置。有时候为了尽量模拟业务场…

半圆阴影_六年级数学:怎么求阴影部分面积?正方形与半圆,割补法常考题

欢迎您来到方老师数学课堂,请点击上方蓝色字体,添加关注。所有的视频内容,全部免费,请大家放心关注,放心订阅。六年级数学:怎么求阴影部分面积?正方形与半圆,割补法常考题。大家先在…

c语言判断整数_用c++编写闰年的判断基础程序

其实c语言与c语言有太多共同的东西,学习过c语言再学习c语言就显得轻而易举。当然学过了c再去学习c语言也是有一些帮助的(但是个人不提倡先学习c在学c语言)。由于现在经常看见有关闰年的程序,风式各样,眼花缭乱,些许凌乱&#xff0…

cat日志 搜索_大日志,看我如何对付你

在服务器接口测试中,我们经常会和各种日志打交道。一旦测试时服务端出现了问题,而单凭服务端的日志又不能发现问题原因的时候,往往开发要向我们测试人员询问客户端这边的情况,希望看看我们能不能提供一些有用信息,如错…

加载gif动图_GIF生成神器——ScreenToGif

每次需要做一个动图展示时,总是感觉很头疼。截图吧,需要的图片太多;录视频吧,文件太大;做动图吧,太麻烦。今天推荐的这个软件或许能够解决大家这个困惑,今天推荐的是动图生成神器——ScreenToGi…

java 修改最大nio连接数_关于java流的几个概念:IO、BIO、NIO、AIO,有几个人全知道?...

关于同步、阻塞的知识我之前的文章有介绍,所以关于流用到这些概念与之前多线程用的概念一样。下面具体来看看java中的几种流IO/BIOBIO就是指IO,即传统的Blocking IO,即同步并阻塞的IO。这也是jdk1.4之前的唯一选择,依赖于ServerSocket实现&am…

python扫雷 广度优先_广度优先搜索(BFS)解题总结

定义 广度优先搜索算法(Breadth-First-Search),是一种图形搜索算法。 简单的说,BFS是从根节点开始,沿着树(图)的宽度遍历树(图)的节点。 如果所有节点均被访问,则算法中止。 BFS同样属于盲目搜索。 一般用队…

python裁剪图片并保存_python – 如何从图像中剪切轮廓并将其保存到新文件中

大家好,这是我的第一个问题所以请保持温和.我有一个计算机视觉领域的项目,我是新的,我会很感激一些帮助.我有一个pcb的图像,我的(首先)任务是从背景中切断电路板并将其保存到新文件.如果结果只是没有灰色背景的普通pcb,那就没问题了. 我到目前为止尝试的是,首先使用阈值将图像转…

flash代码_Flash如何对制作文件进行优化

对FLASH进行优化分为两方面,一方面是代码上的优化,主要是通过优化提高FLASH性能,降低CPU占用和内存使用。另一方面是资源的优化,这方面的优化是为了减小编译后的文件大小以及制作文件的大小,因为如果不进行相应的优化&…

deepin系统转为windows_windows系统下安装深度系统deepin

前期准备DiskGenius(用来扩展分区)deepin-20-amd64.iso(深度系统镜像文件)相关文件下载首先下载安装时要用的工具,分别为:DiskGenius , UltraISODiskGenius是一款磁盘工具,创建系统分区。UltraISO是用来打开系统光盘镜像文件工具。Win8/8.1/10无需下载Ul…

软件开发模型_QT开发(二十三)——软件开发流程

一、软件开发流程简介软件开发流程是通过一系列步骤保证软件产品的顺利完成,是软件产品在生命周期内的管理学。软件开发流程的本质是软件开发流程与具体技术无关,是开发团队必须遵守开的规则。二、常见软件开发流程模型常见的软件开发流程模型包括即兴模…

python3.6.2用pyinstaller3.4报错_OceanBase 2.2 版本体验:用 BenchmarkSQL 跑 TPC-C

OB君:好消息!「 OceanBase 2.2 版本 」正式上线官网啦!(点击阅读原文即可直接下载)OceanBase 2.2版本是成功支撑2019年天猫双11大促的稳定版本,同时也是用于TPC-C测试且荣登TPC-C性能榜首的版本。我们将在接…

hive窗口函数_Hive sql窗口函数源码分析

在了解了窗口函数实现原理 spark、hive中窗口函数实现原理复盘 和 sparksql比hivesql优化的点(窗口函数)之后,今天又撸了一遍hive sql 中窗口函数的源码实现,写个笔记记录一下。简单来说,窗口查询有两个步骤:将记录分割成多个分区…

容大打印机ip修改工具_M1芯片版Mac无法连接打印机怎么办?

文末有优惠券在入手了M1芯片版MacBook Pro后,昨天我打算连接一下实验室的打印机。这个打印机的型号是HP LaserJet Professional M1213nf MFP,在同一个局域网内通过搜索IP即可连接。在我的旧设备2015款MacBook Air上,很轻松就连接了打印机。可…

语音对讲软件_三款语音转文字工具,语音输入,高效转换,准确率高

关于语音转文字的软件我在之前讲了很多,有些人听了也用了,效果不错,有些人看了就忘了,主要是不知道用它干嘛,其实语音转文字的软件主要功能就是为了让自己在写作的时候可以减少时间,提高效率,其…