CPU|java面试——常见的锁和锁升级( 二 )
自旋锁的优缺点优点:避免了锁的使用 , 总体性能比synchronized高很多优点
缺点:存在锁竞争的情况下会造成cpu资源的浪费 , 因为自旋锁一直在让cpu空转直到锁升级到重量级锁
- 尽可能的减少线程的阻塞 , 对于锁竞争不激烈 , 并且占用锁时间较短的代码来说 , 适合用自旋锁 , 因为他的开销相比重量级锁比如synchronized的线程wait和唤醒来说 , 消耗比较小 , 重量级锁在睡眠和唤醒需要切换两次上下文 。
因为cas同时只能有一个线程获取到锁 , 其他都会失败 , 失败了就自旋 , 自旋是不会释放cpu资源的 , 这样就会有大量线程占用cpu资源 , 进而会影响整体系统的性能 , 所以自旋周期的选择就比较重要了 , Jdk1.5这个限度是一定的写死的 , 在1.6引入了适应性自旋锁
自适应自旋锁 - 由前一次在同一个锁上的自旋时间以及锁的拥有者的状态来决定 。
- 如果有半数cpu数个线程正在自旋 , 则后来线程直接阻塞
- 容易造成cpu资源浪费
也就防止在写回去比较的过程中别的线程再次把值修改掉!
lock cmpxchg=cas修改的变量值
再往硬件层面走就是lock锁定了北桥芯片的一个电信号 , 这就没啥意义了
CAS里面的ABA问题如何解决?什么是ABA问题
比如 , 第一个线程把0改为1准备往回写的时候 , 去读取原来的值 , 这个值已经被另外一个线程读取过去先改为2然后再改为0放回去 , 那么此时第一个线程去判断的0其实已经不是原来的那个0了
如何解决ABA问题?很简单 , 在原来那个0上加一个版本号 , 任何值的改动都需要更新版本号 , 当比较的时候除了比较值 , 还要比较版本号 , jdk1.5之后 , 引入AtomicStampedReference类来解决ABA问题 。这个类的compareAndSet方法的作用是首先检查当前引用是否等于预期引用 , 并且检查当前标志是否等于预期标志 , 如果二者都相等 , 才使用CAS设置为新的值和标志 。
如何手写一个自旋锁?
new AtomicReference<>()class MySpinLock{
AtomicReference<Thread> reference = new AtomicReference<>();
public void lock(){
System.out.println(Thread.currentThread().getName()+\" want to get lock\");
//reference空说明还没有线程获取到过
while (!reference.compareAndSet(nullThread.currentThread())){
System.out.println(Thread.currentThread().getName()+\" try to get Lock\");
System.out.println(Thread.currentThread().getName()+\" got the lock\");
public void unLock(){
System.out.println(Thread.currentThread().getName()+\" want to Unlock\");
//解锁的话判断reference是否是当前线程 , 是的话就置为空
reference.compareAndSet(Thread.currentThread()null);
System.out.println(Thread.currentThread().getName()+\" Unlock \");
public static void main(String[
args) {
MySpinLock mySpinLock = new MySpinLock();
new Thread(()->{
mySpinLock.lock();
try {
TimeUnit.SECONDS.sleep(1);
catch (InterruptedException e) {
e.printStackTrace();
mySpinLock.unLock();
\"A\").start();
new Thread(()->{
推荐阅读
- 计算机专业大一下学期,该选择学习Java还是Python
- 未来想进入AI领域,该学习Python还是Java大数据开发
- 2021年换手机哪个配置最重要,CPU只能排第三位
- 8核Zen3 AMD新CPU现身:锐龙7 5700G
- 全新8核国产CPU深入探秘:马上能买到
- 学习大数据是否需要学习JavaEE
- "二八定律"难破 CPU市占率英特尔持续占优
- AMD台式机CPU市场份额15年来首次超越英特尔
- 英特尔Z590平台Logo曝光 酷睿i9-11900K CPU-Z跑分揭晓
- 从事Java开发时发现基础差,是否应该选择辞职自学一段时间
