CAS基础笔记

  • CAS的全称是compare and swap(比较并且交换),是解决多线程安全的一种方法;是一种自旋锁也是乐观锁,而synchronized锁是一种悲观锁。
  • CAS其实是计算机的指令,格式为:(变量内存地址,变量旧值,变量新值)。
  • 在这里插入图片描述
    在这里插入图片描述

CAS cpu层理解

底层硬件通过将 CAS 里的多个操作在硬件层面语义实现上,通过一条处理器指令保证了原子性操作。这些指令如下所示:

(1)测试并设置(Tetst-and-Set)

(2)获取并增加(Fetch-and-Increment)

(3)交换(Swap)

(4)比较并交换(Compare-and-Swap)

(5)加载链接/条件存储(Load-Linked/Store-Conditional)

前面三条大部分处理器已经实现,后面的两条是现代处理器当中新增加的。而且根据不同的体系结构,指令存在着明显差异。

在IA64,x86 指令集中有 cmpxchg 指令完成 CAS 功能,在 sparc-TSO 也有 casa 指令实现,而在 ARM 和 PowerPC 架构下,则需要使用一对 ldrex/strex 指令来完成 LL/SC 的功能。在精简指令集的体系架构中,则通常是靠一对儿指令,如:load and reserve 和 **store conditional ** 实现的,在大多数处理器上 CAS 都是个非常轻量级的操作,这也是其优势所在。

CAS问题:

  1. ABA问题
    线程一:A->B->A
    线程二:A- - - >C
    线程一和线程二同时读取到了变量A到各自的私有内存中,线程一运行的比较快,将变量A变为B后,又变为了A;此时线程二才执行到CAS指令,根据自己保存的变量A地址去内存查看是不是还是A,这个时候发现是A,没有感觉到B存在过,就更新为了C。
  2. 开销问题
    自旋CAS如果长时间操作不成功,会给CPU带来非常大的执行开销。
    3.只能保证一个共享变量的操作
    在这里插入图片描述

解决:

主要是ABA问题:
线程一:A1 ->B1 ->A2
线程二:A1-> -> 发现变量A值不是A1,重新读取。
增加版本戳,每次修改变量后,同步更新变量的版本号。
可以使用AtomicMarkableReference ->返回变量是否变动过
AtomicStampedReference ->返回变量变动过几次

原子操作类

在这里插入图片描述
基本使用:
AtomicInteger ai = new AtomicInteger(10);
ai.getAndIncrement(); – 返回原先的值10
ai.incrementAndGet(); --返回增加后的值11
在这里插入图片描述

思考 synchronize为什么比CAS要慢?

synchronize使用后,其他线程就处于阻塞状态,而要唤起,需要进行上下文的切换。而且synchronize使用要进行加锁、释放锁等操作,指令执行时间长。

LOCK显示锁

lock锁为什么比synchronize锁慢?

synchronize锁从jdk1.5之后一直在不断的优化,效率一直在提升,而且是java自带的内置锁。但是lock锁只是一个接口,使用的时候需要实例化,所以一般在没有尝试获取锁、中断锁这些需求的场景下,一般使用synchronize锁。

公平锁与非公平锁

非公平锁理解:
在这里插入图片描述
一个在使用锁的线程执行完后,其他阻塞的线程要进行唤醒,此时要进行上下文切换。而如果此时刚好有一个线程处于等待状态,不用进入阻塞队列里,直接获取到锁使用,就是非公平锁。

非公平锁效率高原因分析

一个锁被使用的时候,其他线程要处于阻塞状态,而如果要将这些阻塞的线程唤醒就意味着要进行上下文的切换,在计算机中上下文切换是很耗时的操作;
假如:一个线程使用完锁了,此时操作系统去唤醒阻塞线程去了,这个时候锁处于空着状态,而同时有另一个新线程进来了,也要获取这个锁,如果是非公平锁的话,就直接给这个线程使用了,这个线程就不用进入这个锁的阻塞队列等待了。如果新线程执行完了,阻塞线程也刚好上下文切换完成,这样就大大提高了效率。

synchronized是非公平锁;
ReentraLock默认也是非公平锁。

公平锁用处

既然非公平锁效率高为什么还有公平锁呢?那是因为在非公平锁的情况下,可能会出现线程饥饿的情况,所以为了保证所有线程都能被执行,会用到公平锁。

推荐个很好的博客来理解CAS

https://www.cnblogs.com/ldws/p/11970087.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值