CAS机制详解,字节跳动大神讲座

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();

public final int incrementAndGet() {

return unsafe.getAndAddInt(this, valueOffset, 1) + 1;

}

}

public final class Unsafe {

public final int getAndAddInt(Object var1, long var2, int var4) {

int var5;

do {

var5 = this.getIntVolatile(var1, var2);//先获取期望值

} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));

//如果比较和交换失败,就会一直重试,直到成功位置

return var5;

}

public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);

}

在这里我们看到了Unsafe类,它在 package sun.misc 目录下面,并不在SDK中。

Unsafe是一个功能强大的类,它可以像C/C++一样 直接操作对象内存,修改jvm运行时的数据,它的操作粒度不是类,而是直接针对数据和地址,有点类似于C/C++中的指针。

我们在23行看到了CAS,就是 compareAndSwapInt() 方法,它是一个本地方法,我们无法再深入看下去。

1.5 详细解析CAS


CAS是英文单词Compare And Swap的缩写,翻译过来就是比较并替换。

CAS机制当中使用了3个基本操作数:内存地址V,旧的预期值A,要修改的新值B。

更新一个变量的时候,只有当变量的预期值A和内存地址V当中的实际值相同时,才会将内存地址V对应的值修改为B。

这样说或许有些抽象,我们来看一个例子:

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
img

最后

我见过很多技术leader在面试的时候,遇到处于迷茫期的大龄程序员,比面试官年龄都大。这些人有一些共同特征:可能工作了7、8年,还是每天重复给业务部门写代码,工作内容的重复性比较高,没有什么技术含量的工作。问到这些人的职业规划时,他们也没有太多想法。

其实30岁到40岁是一个人职业发展的黄金阶段,一定要在业务范围内的扩张,技术广度和深度提升上有自己的计划,才有助于在职业发展上有持续的发展路径,而不至于停滞不前。

不断奔跑,你就知道学习的意义所在!

以上进阶BATJ大厂学习资料可以免费分享给大家,需要完整版的朋友,【点这里可以看到全部内容】。

试官年龄都大。这些人有一些共同特征:可能工作了7、8年,还是每天重复给业务部门写代码,工作内容的重复性比较高,没有什么技术含量的工作。问到这些人的职业规划时,他们也没有太多想法。

其实30岁到40岁是一个人职业发展的黄金阶段,一定要在业务范围内的扩张,技术广度和深度提升上有自己的计划,才有助于在职业发展上有持续的发展路径,而不至于停滞不前。

不断奔跑,你就知道学习的意义所在!

以上进阶BATJ大厂学习资料可以免费分享给大家,需要完整版的朋友,【点这里可以看到全部内容】。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值