CAS机制

今天来说一说Java中的CAS机制,在此之前,先了解两个概念:悲观锁和乐观锁

悲观锁:线程获取锁(JDK1.6之前内建锁)是一种悲观锁的策略,假设每一次执行临界区代码(访问共享资源)都会产生冲突,所以当前线程获取到锁的同时也会阻塞其他未获取到锁的线程。
乐观锁(无锁操作):假设所有线程访问共享资源是不会出现冲突,由于不会出现冲突自然就不会阻塞其他线程,因此线程就不会出现阻塞停顿的状态。当出现冲突时,无锁操作使用CAS(比较交换)来鉴别线程是否出现冲突,出现冲突就重试当前操作直到没有冲突为止。
接下来来看一下CAS的操作过程:
CAS 可通俗理解为CAS(V,O,N),其中
V 表示—>当前内存地址实际存放的值
O 表示—>预期值(旧值)
N 表示—>更新的新值

当V=O时:期望与实际值相等,该值没有被其他线程修改过,即值O就是目前最新的值,此时可将新值N赋给V,反之,表明该值已被其他线程修改,此时O值并不是当前最新值,返回V,无法修改。
当多个线程使用CAS操作时,只有一个线程会成功,其余线程均失败,失败线程会重新尝试(自旋)或挂起(阻塞)线程
内建锁在优化前最大的问题在于:在存在线程竞争的情况下会出现线程的阻塞及唤醒带来的性能问题,这是一种互斥同步(阻塞同步)
而CAS不是将线程挂起,当CAS失败后会进行一定的尝试操作并非耗时地将线程挂起,也叫非阻塞同步。
CAS存在的的问题:
(1)ABA问题
这里先来说一说什么是ABA问题
假设内存中有一个变量X,存贮在地址V中。此时有三个线程想使用CAS方式来更新这个变量值。因为每个线程执行时间略有偏差所以发生了下面的情况:
在这里插入图片描述
这个过程中,线程2获取到的变量X是一个旧值,但由于中间阻塞,使得最后当前值变为了新X,虽然和原来值相同,但变量已经经历了X–>Y–>X的转变,这就是ABA问题
解决:
使用atomic AtomicstampedReference类来解决(添加版本号:1A–>2B–>3A)

(2)自旋会浪费大量的CPU资源
与线程阻塞相比,自旋会浪费大量的处理器资源,因为当前线程仍处于运行状态,只不过跑的是无用指令
解决:自适应自旋(根据以往自旋的能否获取锁来动态调整自旋时间,若能下次增加自旋时长,若不能,下次减少自旋时长)
(3)公平性
内建锁无法实现公平机制,而lock体系可以实现公平锁。(lock体系后续在讲)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值