java多线程-理解CAS

- 扯皮

为什么要研究CAS,因为AQS的底层就是CAS实现的,为什么研究AQS,在AQS篇幅了。

  • 原子性

顾名思义,和化学领域的原子概念一样,就是不可再拆分的物质。
在java多线程里的原子性,意思是在多线程环境下,线程安全的操作就是原子性 操作!比如:即使一个 1000行代码的方法,在方法上使用最重量级的synschonized了,那么这1000行代码也是原子性操作!和代码多少没有关系!例如下面的num++。

  • JVM原子性操作

JVM内存模型规定的原子性操作有8个,read、load、use、asign、store、write、lock、unlock
就是在JVM的规定下,只有这几个操作是原子性的,不会存在多线程下不安全的情况。
除此之外,无法保证!

  • num ++操作

num++ 操作是非原子操作,虽然简单的一行代码,但是在JVM里,先宽泛的 认为包含了几个步骤:
a):主内存read+load到工作内存。 b):工作内存use到cpu,cpu进行+1,然后进行asign到工作内存。
c):然后再从工作内存store+write到主内存。
即使使用了volatile,也是需要通过工作内存到主内存的过度,强制刷新到其他线程的工作内存中。也是无法保证原子性的。
该篇文章涉及到JVM内存模型等知识点,会有篇幅单独讨论。这里只简单阐述num++非原则性操作。

  • CAS解读

CAS(Compare-and-Swap),即比较并替换。
白话:就是利用了java中的Unsafe类,这个类和JVM约定好了,我这个类玩的是直接和底层cpu、物理内存打交道了。不走你JVM约定的内存模型的规则了 。除此之外,都是受你JVM内存模型约束。
核心思想: 执行函数:CAS(V,E,N)
V:内存地址,就是你变量在哪了啊
E:当前我希望你的值
N:我希望把你改成的值
比如现在内存中有个变量state初始是0。
有一个线程1来了,执行CAS(变量地址,0,1)。结果就是state由0改成1了。
如果瞬间来了1000个线程呢?如何保证线程不会争抢呢?cpu指令保证的。。感觉有点玩赖了。
线程1执行完state=1了,那么剩下的999个线程呢?一看state=1了,再执行CAS(变量地址,0,1)时,执行不了了,我希望你的值是0,但是你是1啊。没达成共识,没法玩了。那就不玩了。该线程1该干嘛干嘛去吧。
在AQS中,大量的这个套路,就是for( ; ; ) 死循环+CAS操作。所以线程1接着回来再次尝试!
真正的原子性保障还是cpu指令做到的 。至于cpu如何做到的。别扯了。目前的目标就是先把CAS理论先理解下。哈哈

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值