CAS机制详解,android快速开发框架
作者:互联网
CAS(V,E,N) 机制当中使用了3个基本操作数:内存地址V,旧的预期值A,要修改的新值B。
更新一个变量的时候,只有当变量的预期值A和内存地址V当中的实际值相同时,才会将内存地址V对应的值修改为B。
先来实现一段代码
1.1、Demo1
public class Demo1 {
int i = 0;
public void incr() {
i++;//加1操作
}
public static void main(String[] args)throws Exception {
Demo1 demo1 = new Demo1();
for (int j = 0; j < 2; j++) {//new 两个线程
new Thread(new Runnable() {
@Override
public void run() {
for (int k = 0; k < 10000; k++) {//每个线程执行10000遍
demo1.incr();
}
}
}).start();
}
Thread.sleep(1000);
System.out.println(demo1.i);//打印结果是否为20000?
}
}
打印结果:
可能是20000,更多的是小于20000的整数,
运行多次后可以看到,打印结果是小于20000的。为什么会出现这样的结果呢?
这是因为 incr() 方法中的 i++ 操作不是原子性的,这就意味这它会被干扰。
在IDEA中,我们使用Show ByteCode(反编译字节码)看它的字节码文件:
再来看 incr() 方法中的 i++ 它实际上被分成了多步操作,因此不具备原子性
private incr()V
L0
LINENUMBER 7 L0
ALOAD 0
DUP
GETFIELD com/ph/cas/Demo1.i : I //获取字段值
ICONST_1
IADD //相加
PUTFIELD com/ph/cas/Demo1.i : I //赋值
L1
LINENUMBER 8 L1
RETURN
L2
LOCALVARIABLE this Lcom/ph/cas/Demo1; L0 L2 0
MAXSTACK = 3
MAXLOCALS = 1
1.2、什么是原子操作?
原子操作可以是一个步骤,也可以是多个步骤,但是其顺序不可以被打乱,也不可以被切割而只执行其中的一部分(不可中断性)。将整个操作视作一个整体是原子性的核心特征。
1.3、JDK中相关原子操作类
1.3.1、原子更新基本类型,
Atomic包提供了以下3个类。·AtomicBoolean AtomicInteger AtomicLong。
1.3.2、原子更新数组类型
AtomicIntegerArray:原子更新整型数组里的元素。
AtomicLongArray:原子更新长整型数组里的元素。
·AtomicReferenceArray:原子更新引用类型数组里的元素。
1.3.3、原子更新引用类型
AtomicReference:原子更新引用类型。
AtomicMarkableReference,AtomicStampeReference
1.3.4、原子更新字段类
AtomicIntegerFieldUpdater:原子更新整型的字段的更新器。
AtomicIntegerFiledUpdater,AtomicLongFiledUpdater
下面我们对Demo1进行优化:
1.4、优化Demo2
public class Demo2 {
AtomicInteger i = new AtomicInteger(0);
private void incr(){
i.incrementAndGet();//对变量加1操作,并返回(原子操作)
}
public static void main(String[] args)throws Exception {
Demo2 demo2 = new Demo2();
for (int j = 0; j < 2; j++) {//new 两个线程
new Thread(new Runnable() {
@Override
public void run() {
for (int k = 0; k < 10000; k++) {//每个线程执行10000遍
demo2.incr();
}
}
}).start();
}
Thread.sleep(1000);
System.out.println(demo2.i);//打印结果是否为20000?
}
}
打印结果:20000
我们来看 inrc() 的字节码文件:
private incr()V
L0
LINENUMBER 10 L0
ALOAD 0
GETFIELD com/ph/test/Demo2.i : Ljava/util/concurrent/atomic/AtomicInteger;
INVOKEVIRTUAL java/util/concurrent/atomic/AtomicInteger.incrementAndGet ()I
POP
接下来进行深入研究:
AtomicInteger i = new AtomicInteger(0);
private void incr(){
i.incrementAndGet();//对变量加1操作,并返回(原子操作)
}
public class AtomicInteger extends Number implements java.io.Serializable {
private static final Unsafe unsafe = Unsafe.getUnsafe();
总结
我最近从朋友那里收集到了2020-2021BAT 面试真题解析,内容很多也很系统,包含了很多内容:Android 基础、Java 基础、Android 源码相关分析、常见的一些原理性问题
等等,可以很好地帮助大家深刻理解Android相关知识点的原理以及面试相关知识。
这份资料把大厂面试中常被问到的技术点整理成了PDF,包知识脉络 + 诸多细节;还有 高级架构技术进阶脑图 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。
这里也分享给广大面试同胞们,希望每位程序猿们都能面试成功~
Android 基础知识点
Java 基础知识点
Android 源码相关分析
常见的一些原理性问题
腾讯、字节跳动、阿里、百度等BAT大厂 2019-2020面试真题解析
能面试成功~
Android 基础知识点
[外链图片转存中…(img-ORmnuL8w-1643529203111)]
Java 基础知识点
[外链图片转存中…(img-mfPxVxAI-1643529203112)]
Android 源码相关分析
[外链图片转存中…(img-YhmGd3IG-1643529203112)]
常见的一些原理性问题
[外链图片转存中…(img-EyNDHjRx-1643529203113)]
腾讯、字节跳动、阿里、百度等BAT大厂 2019-2020面试真题解析
[外链图片转存中…(img-ApETEkQE-1643529203113)]
标签:incr,CAS,AtomicInteger,原子,public,详解,new,android,Android 来源: https://blog.csdn.net/m0_66264533/article/details/122753495