AutomaticInteger中CAS运用分析
摘要
在接触CAS的时候虽然对它流程了解了但是对其如何解决并发问题还是一直有疑问的,所以在就选择了java中典型线程安全的AtomicInteger类进行了源码的分析。
CAS简介
CAS的全称为compare and swap简单的解释为比较交换,这个过程其实是发生在内存中的,应该说是汇编语言的一个操作过程。那么乐观锁为什么用CAS算法呢?简单的来说就是乐观锁每次操作的时候都认为不会发生并发,但是为了安全还是会去检测是否并发了,这样的话不用sync耗费太大性能
正文
接下来就开始说正文。我们先从AtomicInteger类的incrementAndGet()的方法解析吧,代码如下所示:
public final int incrementAndGet() {
return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}
OK,这是一段非常简单的代码至于为什么把它拿出来是因为我觉得我有必要凑一下字数不然显的我写的第一篇文章实在是太短了。不过这里有个东西我要解释一下就是这个valueoffset,这个是AtomicInteger中被volatile关键字修饰的value在内存中的偏移量,嗯,贴个代码占点字数。
static {
try {
valueOffset = unsafe.objectFieldOffset
(AtomicInteger.class.getDeclaredField("value"));
} catch (Exception ex) { throw new Error(ex); }
}
可以看出来这个偏移量在类加载过程中就得到了,接下来咱们点击去getAndAddInt方法内,代码如下所示:
public final int getAndAddInt(Object var1, long var2, int var4) {
int var5;
do {
var5 = this.getIntVolatile(var1, var2);//1
} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));//2
return var5;
}
上面这段代码就是咱们要说的重点了,先忽略编号为1的代码,我们先看代号为2的代码行。方法compareAndSwapInt方法有四个参数,解释一下:
var1:对象的引用;
var2:值的偏移量;
var3:期望值;
var4:更新值;
我们接下来对这个方法的功能解释一下,这个方法它是一个本地方法,它底层是C++写的,里面到底是什么大家可以在网上搜很多资料来查看,这里我我通俗的给大家说明一下。这个方法的作用就是拿着对象的引用以及位偏移量从内存中拿到值,然后拿着这个值和期望值进行一个比较,如果相同则将要更新的值放到内存中返回true如果不同则返回false.说到这里大家可能就知道这就是一次CAS了,那现在我们说一下编号为1的那行代码是干嘛的,简单的来说就是从内存中拿到value值(它到底底层是如果实现的大家也可以上网上搜搜)。
好,现在我们就开始解释一下这个方法,首先从内存中拿到value的值,然后将这个值作为compareAndSwapInt方法的期望值,然后再将对象的引用和值偏移量作为var1参数和var2参数,然后带上更新值执行compareAndSwapInt方法,之后就是等待返回true和flase然后判断时候做循环。OK讲到这里估计大家就比较清楚了,对于C++里面你是怎么保证原子性的请在百度框搜索"java cas 详解"。
总结
怎么说?嗯,因为网上对cas的解释多的数不胜数所以就没有再去粘贴和总结那些知识点也请大家多多包涵,对于本文的问题请大伙积极指出我一定研究并修改,希望能互相促进学习。END !
AutomaticInteger中CAS运用分析的更多相关文章
- Java中CAS原理分析(volatile和synchronized浅析)
CAS是什么? CAS英文解释是比较和交换,是cpu底层的源语,是解决共享变量原子性实现方案,它定义了三个变量,内存地址值对应V,期待值E和要修改的值U,如下图所示,这些变量都是在高速缓存中的,如果两 ...
- 【漫画】CAS原理分析!无锁原子类也能解决并发问题!
本文来源于微信公众号[胖滚猪学编程].转载请注明出处 在漫画并发编程系统博文中,我们讲了N篇关于锁的知识,确实,锁是解决并发问题的万能钥匙,可是并发问题只有锁能解决吗?今天要出场一个大BOSS:CAS ...
- java8中CAS的增强
注:ifeve.com的同名文章为本人所发,此文在其基础做了些调整.转载请注明出处! 一.java8中CAS的增强 前些天,我偶然地将之前写的用来测试AtomicInteger和synchronize ...
- Android中AppWidget的分析与应用:AppWidgetProvider .
from: http://blog.csdn.net/thl789/article/details/7887968 本文从开发AppWidgetProvider角度出发,看一个AppWidgetPrv ...
- JAVA WEB 中的编码分析
JAVA WEB 中的编码分析 */--> pre.src {background-color: #292b2e; color: #b2b2b2;} pre.src {background-co ...
- Android 中图片压缩分析(上)
作者: shawnzhao,QQ音乐技术团队一员 一.前言 在 Android 中进行图片压缩是非常常见的开发场景,主要的压缩方法有两种:其一是质量压缩,其二是下采样压缩. 前者是在不改变图片尺寸的情 ...
- 《构建之法》教学笔记——Python中的效能分析与几个问题
<构建之法:现代软件工程>中第2章对效能分析进行了介绍,基于的工具是VSTS.由于我教授的学生中只有部分同学选修了C#,若采用书中例子讲解,学生可能理解起来比较困难.不过所有这些学生都学习 ...
- Java原子类中CAS的底层实现
Java原子类中CAS的底层实现 从Java到c++到汇编, 深入讲解cas的底层原理. 介绍原理前, 先来一个Demo 以AtomicBoolean类为例.先来一个调用cas的demo. 主线程在f ...
- Apollo配置中心源码分析
Apollo配置中心源码分析 1. apollo的核心代码分享 SpringApplication启动的关键步骤 在SpringApplication中,会加载所有实现了Init方法的类 protec ...
随机推荐
- C++暑期学习笔记
# C++初步学习笔记 一.命名空间(namespace)相关 1 个人理解: 为了避免整合资源中存在的重名矛盾而采取的区别资源的措施: 2 命名空间的定义: 比如要定义一个命名空间A: namesp ...
- IOS和安卓WEB页面,input输入框被软键盘遮挡解决方法
本来以为这问题就只有ios才有,身边也没有android机测试,网上一搜,貌似有这个问题的还不少.最后把各种解决方法试了一边,貌似没什么用. 最后是这样解决的: setInterval(functio ...
- 4-1 R语言函数 lapply
#lapply函数 #可以循环处理列表中的每一个元素 #lapply(参数):lapply(列表,函数/函数名,其他参数) #总是返回一个列表 #sapply:简化结果 #结果列表元素长度均为1,返回 ...
- performSelector 多参调用的实现方案
1.nsinvocation封装: 2.msg_send封装: 第二种方案是系统的原生封装.
- POJ 3294 Life Forms [最长公共子串加强版 后缀数组 && 二分]
题目:http://poj.org/problem?id=3294 Life Forms Time Limit: 5000MS Memory Limit: 65536K Total Submiss ...
- nodejs的expresss中post的req.body总是undefined的原因
1)因为express将body-parser分离了出来,所以你需要手动添加进下面的内容即可 var path = require('path'); var bodyParser = require( ...
- django restframework 简单总结
官方文档:http://www.django-rest-framework.org/ model.py class Snippet(models.Model): created = models.Da ...
- 优化方法:SGD,Momentum,AdaGrad,RMSProp,Adam
参考: https://blog.csdn.net/u010089444/article/details/76725843 1. SGD Batch Gradient Descent 在每一轮的训练过 ...
- 添加打印功能 iOS
app直接调取系统的打印功能 https://blog.csdn.net/wsyx768/article/details/79098885
- 定义一个复数(z=x+iy)类Complex,包含: 两个属性:实部x和虚部y 默认构造函数 Complex(),设置x=0,y=0 构造函数:Complex(int i,int j) 显示复数的方法:showComp()将其显示为如: 5+8i或5-8i 的形式。 求两个复数的和的方法:(参数是两个复数类对象,返回值是复数类对象)public Complex addComp(Compl
因标题框有限,题目未显示完整,以下再放一份: 定义一个复数(z=x+iy)类Complex,包含: 两个属性:实部x和虚部y 默认构造函数 Complex(),设置x=0,y=0 构造函数:Compl ...