大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?

举报
mikechen的互联网架构 发表于 2024/11/13 22:58:09 2024/11/13
【摘要】 本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。

关注△mikechen的互联网架构△,10年+BAT架构经验倾囊相授


image.png

大家好,我是 mikechen | 陈睿

Java面试经常问到自旋锁相关的问题,什么是自旋锁?Java如何实现自旋锁?自旋锁的底层原理是怎样的?下面一一详解@mikechen

什么是自旋锁?

自旋锁(spinlock):是指当一个线程在获取锁的时候,如果锁已经被其它线程获取,那么该线程将循环等待,然后不断的判断锁是否能够被成功获取,直到获取到锁才会退出循环。

这种采用循环加锁,等待锁释放的机制就称为自旋锁(spinlock)

自旋锁的优缺点

自旋锁的优点:

性能较高:自旋锁不会使线程状态切换,始终处于用户态,即线程始终处于活动状态,不会让线程进入阻塞状态,减少不必要的上下文切换,性能较高。

自旋锁避免了进程上下文的调度开销,因此对于线程只会阻塞很短时间的场合是有效的,所以相比互斥锁来说,会快一些开销。

自旋锁的缺点

1)死锁:试图递归地获得自旋锁必然会引起死锁:递归程序的持有实例在第二个实例循环,以试图获得相同自旋锁时,不会释放此自旋锁。

2)在等待锁时进入循环会占用CPU,若等待的线程很多,对CPU的消耗会比较大。

3)不适合需要长时间等待的任务或线程,不适合大量线程等待的场景。

自旋锁的使用场景

1)等待时间比较短的任务中;

2)线程数量不太多的应用中;

3)当等待时间长或线程数量很大时,可以使用其他锁(比如:可重入锁)。

Java如何实现自旋锁?

我们来看一个Java实现的例子:

public class SpinLock {
 
private AtomicReference<Thread> cas = new AtomicReference<Thread>();
 
public void lock() {
 
Thread current = Thread.currentThread();
 
// 利用CAS
 
while (!cas.compareAndSet(null, current)) {
 
// DO nothing
 
}
 
}
 
public void unlock() {
 
Thread current = Thread.currentThread();
 
cas.compareAndSet(current, null);
 
}
 
}

lock获取锁的方法利用的CAS,当第一个线程A获取锁的时候,能够成功获取到,不会进入while循环,如果此时线程A没有释放锁,另一个线程B又来获取锁,此时由于不满足CAS,所以就会进入while循环,不断判断是否满足CAS,直到A线程调用unlock方法释放了该锁。

Java并发包中的很多类,都使用了CAS技术,是实现我们平时所说的自旋锁或乐观锁的核心操作。

CAS的算法

它的实现很简单,就是用一个预期的值和内存值进行比较,如果两个值相等,就用预期的值替换内存值,并返回 true。否则,返回 false。

CAS机制当中使用了3个基本操作数:内存地址V,旧的预期值A,要修改的新值B

更新一个变量的时候,只有当变量的预期值A和内存地址V当中的实际值相同时,才会将内存地址V对应的值修改为B

CAS的实现原理

image.png

如上图显示,线程1、线程2同时修改值。

如果通过CAS来实现,具体流程如下:

  1. 在内存地址V当中,存储着值为7的变量
  2. 线程1想要把变量的值增加1,对线程1来说,旧的预期值A=7,要修改的新值B=8
  3. 线程2抢先一步,把内存值V修改:8
  4. 线程1开始提交更新,首先对比了预期值A=7和实际值V的比较8(Compare),发现A不等于V的实际值,提交失败

以上,是自旋锁及Java实现自旋锁原理的详细解析,欢迎评论区留言交流或拓展。

我是 mikechen | 陈睿 ,关注【mikechen的互联网架构】,10年+BAT架构技术倾囊相授。

本文已同步我的技术博客 www.mikechen.cc,更新至我原创的《30W+字大厂架构技术合集》中。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。