悲观锁,乐观锁,CAS初步了解

从零开始

互斥锁(悲观锁)

在这里插入图片描述
如果多个线程想要操作一个资源。我们使用互斥锁进行资源同步,但是互斥锁的同步方式是悲观的:

简单来说,就是系统会悲观的认为,如果我们不严格同步线程调用,那么一定会产生线程资源异常。
所以互斥锁将会把资源锁定,在一个线程访问此资源时阻塞其他线程,以此来达到多线程资源同步。

那么问题在于?这样虽然能保证多线程资源安全,但是如果多线程只是进行读的操作,那么这样会进行大量的线程切换,耗时严重。
甚至有些时候,哪怕是专门进行线程同步,也比线程切换耗费时间少。

CAS

那么我们可以想屁吃,比如不锁定资源,还能同步线程资源么?
那么就要用到CAS(compare and swap)说人话就是先比较再交换。
如果线程A和线程B同时访问一个资源,此时资源的值为0,那么线程A和线程B会读取这个0值作为old value(之前读的状态),假如他们都想把这个资源的值改为1,那么这两个线程的new value(目标结果状态)。如果此时,线程A分到时间片,改变资源为1,那么在线程B分到时间片访问资源,他会先比对old value和资源现在的状态,如果不一致,他会放弃修改(其实线程A访问资源时也进行了此操作,只是省略了),进行自旋(不断进行CAS操作,不会死循环默认10次可更改)。
在这里插入图片描述

乐观锁(无锁)

由于我们通过CAS来实现了多线程资源同步,并没有锁定资源,所以线程每次都会乐观的认为在访问过程中资源没有被修改,会主动去比较状态值(old value),这就是乐观锁(并没有用到锁,甚至可以叫无锁)。

CAS原子性和实际调用

我们仔细想CAS流程,说了这么多,他也只有比较和交换两个流程,并没有进行同步操作,那么他不还是不安全的,比如说线程A和线程B同时对资源和old value进行比对呢?
所以CAS流程首先需要保证原子性。
那么我们使用CAS的需要怎么操作:
我们需要访问unsafe对象的CAS方法:
在这里插入图片描述
我们继续查看CAS方法,发现他有native修饰符,代表是个本地方法,会根据不同平台调用不同的方法。(ps:native里的本地方法是用c++编写的,JVM有讲)
在这里插入图片描述
native会根据你cpu的架构调用不同的指令集(硬件基础知识,再进入native的本地方法,会发现具体方法体内使用了汇编语言控制硬件。至此。

=============================================================================

杂七杂八

刚学java就知道java代码实际上是跑在虚拟机JVM上的,这也是java能跨平台运行的核心原因,甚至对于虚拟机的内存结构也学习了解过几次了,但是到这次查CAS的底层才发现,还有别的语言内核也是基于JVM。
例如:Groovy,Jruby等。属于是少见多怪了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值