JAVA之CAS操作

CAS操作

一、什么是CAS操作?
  • 首先来说一下悲观锁策略

    线程在获取锁的时候,采取的是一种悲观锁的策略。即认为每执行一次临界区代码都会产生冲突,所以当前线程获取锁的时候也会阻塞其他线程获取锁。

  • CAS操作

    CAS操作又称无锁操作,采取的是一种***乐观锁***的策略,即***它假设所有线程资源在访问共享资源时不会出现冲突***,所以不会阻塞其他线程的操作。因此线程不会出现阻塞停顿的状态。

    那么如果真的出现了冲突怎么办?无锁操作是使用***CAS(Compare And Swap)***,即字面意思,比较和交换,以此来鉴别线程是否出现冲突,出现了冲突就重试当前操作直到没有冲突为止。

二、CAS操作过程
  • 首先我们可以假想有这么一个方法 CAS(V, O, N),其三个参数分别意为:V内存地址存放的实际值,O预期的值(旧的值),N更新的新值。
  • 当O和V相同时,即旧值和内存中实际的值相同,表明该值没有被其他线程修改过,旧值O就是目前来说最新的值了,自然就可以将新值N赋给V了。
  • 当O和V不同时,表明该值被其他线程修改过了,旧值O不是最新版本的值,所以不能将N赋给V,返回V即可。
  • 另外,当 多个线程使用CAS操作一个变量时,只有一个线程会成功,并成功更新,其余则会失败。当然,失败的线程会重新尝试,也可以选择挂起。

TIPS:CAS操作的实现需要硬件指令集的支持,在JDK1.5以后的虚拟机才可以实现。而且CAS并不会将线程就那么简单的挂起,CAS失败以后会进行一定的尝试,而非进行进行耗时的挂起或者唤醒操作,也称为非阻塞同步。

三、CAS的问题
  1. 用一个例子来讲,就是一个是***从A变成B,又从B变成A***,CAS检查时发现旧值依然与新值相等,但是实际上发生了变化。这里我们的解决方案就是类似版本管理工具之类的作法,添加一个版本号。
  2. 自旋会浪费处理器资源,(自旋: 如同前面说的CAS失败不会立即挂起,而是继续争夺一段时间,而后才放弃),这里我们采取的策略是,如果在一定时间内获取到了资源,那么下次延长这个时间,如果没有获取到,那么下次减短这个时间。
  3. 不公平,处于阻塞状态的线程无法获取刚释放的资源,而处于自旋状态的线程很有可能会优先获得这把锁。

TIPS: 内建锁无法实现公平机制,而Lock体系可以实现公平锁。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值