java OS基本锁,CAS,原子操作类 笔记

本文深入探讨了CPU执行级别的切换机制,包括内核态与用户态之间的转换,以及上下文切换的不同场景。详细介绍了OS级别的锁机制,如互斥锁、自旋锁和信号量的工作原理,并讨论了CAS机制在并发控制中的应用,以及其在JDK中的具体实现,如ConcurrentHashMap。同时,文章分析了CAS机制存在的问题,如ABA问题和时间开销问题,并提出了相应的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

内核态/用户态

CPU的执行级别切换,0,1,2,3
0 内核级别
1
2 用户级别
3

上下文切换:

1.进程与进程切换
2.进程内部内核态与用户态切换
3.线程与线程切换
4.线程与外部进程的线程切换

OS级别的锁

1.互斥锁 pthread_mutex,如果拿不到锁则睡眠,进入内核态,因为发生了一次系统调用
2.自旋锁 pthread_spin_t ,即spinLock,如果拿不到锁,一直死循环空转,OS内部处理
3.信号量 

CAS(Compare and Swap)简述

原子操作:对于一堆操作,要么全部完成,要么全部失败,例如:事务
乐观锁思想的一个体现,无锁编程
CAS 本质是自旋(死循环),比较旧值是否为期望的值, 如果是,则更新为新值, 如果不是,则重新取旧值作为期望值,重新计算,然后再比较旧值与期望值是否相同…如此反复,直到旧值与期望值相同
在这里插入图片描述
使用现代CPU都支持的 CAS:cmpxchg指令(内存地址, 旧值,新值) 来保证CAS的可靠性,耗时大约0.6ns(纳秒)一次

JDK中大量实现CAS机制
例:ConcurrentHashMap , 在1.8以前用的悲观锁/显式锁,1.8后使用CAS

CAS的问题:

  1. ABA问题,说明:有一个变量值为A, 线程1与线程2同时来修改A, 线程1比较快速, 把A改成C,又改回了A, 这个时候线程2也在改,A改成B , 这个时候线程2是发现不了这个变量曾经变成了C,又变回到A. 如何解决:在变量上加修改版本号, CAS时除了比较值外,还要比较版本号

  2. 时间开销问题:CAS是个纯计算性的问题, 如果长时间未成功, 会占用较长时间

  3. 只能保证一个共享变量的原子操作:因为cpu的cas指令只能针对一个内存地址,所以每次只能处理一个地址的变量 如何解决:将多个变量合并为一个类,使用JDK的原子操作类: AtomicXXXXX
    在这里插入图片描述
    用于解决ABA问题的类
    AtomicMarkableReference 只会标记旧值是否有修改
    AtomicStampedReference 会记录旧值被修改了多少次(版本号)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值