多线程进阶--面试常见知识点

1 常见的锁策略

1.1 乐观锁vs悲观锁

悲观乐观是对后续锁冲突是否频繁做出的预测。

如果预测接下来发生锁冲突的概率不大,就可以少做一些工作,就称为乐观锁;

如果预测接下来发生锁冲突的概率较大,就需要多做一些工作,就称为悲观锁。

1.2 重量级锁vs轻量级锁

重量级锁,锁的开销较大;轻量级锁,锁的开销较小。

通常,乐观锁就是轻量级锁,悲观锁就是重量级锁。

1.3 自旋锁vs挂起等待锁

自旋锁是轻量级锁的的一种典型实现,往往在用户态进行,例如使用一个while循环,不断判断当前锁是否被释放,如果没释放,就继续循环,如果已经释放,就获取到锁并结束循环。(忙等,消耗cpu但是换来了更快的响应速度);

挂起等待锁要借助系统api来实现,一旦出现锁竞争,就会在系统内核中执行一系列的操作(比如让这个线程进入阻塞状态,不参与cpu的调度,而阻塞的开销通常是很大的)。

1.4 读锁vs写锁

读锁:读的时候别的线程可以读,但是不可写。

写锁:写的时候别的线程不可以读,也不可以写。

1.5 公平锁vs非公平锁

当一堆线程等待锁释放想要拿到锁的时候,该按照什么策略拿呢?

公平锁:先来的线程先拿到锁。(先来后到)

非公平锁:每个线程以相同的概率竞争锁。

以上策略都是锁的一些特点,那前面说过的synchronized属于哪种锁呢?

1、对于"悲观乐观"是自适应的。

2、对于"重量轻量"是自适应的。

3、对于"自旋挂起"是自适应的。

4、不是读写锁。

5、是可冲入锁。

6、是非公平锁。

对于初始情况,synchronized会预测锁冲突的概率不大,此时以乐观锁的模式来运行(也就是轻量并且自旋的);如果后续锁冲突的概率加大,那么此时就会自适应的变为悲观锁(也就是重量挂起的)。

2 CAS

CAS就是compare和swap,也就是比较并且交换,那它比较的是什么呢?是内存和寄存器中的值。

CAS(M,A,B):比较M和A的值,如果相同,就把M和B的值交换,返回true;如果不同,就什么都不做,直接返回false。

这是CAS的伪代码:

CAS本质上是cpu提供的一个指令,是具有原子性的,之后又被操作系统封装,提供api,又被JVM封装,也提供api,最后供程序员使用。

既然CAS是具有原子性的,那么它也可以解决"线程安全"问题,从而在一些场景中代替加锁策略,基于CAS实现"线程安全"的编程称为无锁编程。这样做的好处是什么呢:不仅可以保证线程安全,同时比加锁的效率更高;但是,也存在一些缺点:1、代码会更复杂,不好理解 2、仅使用于一些场景,不如加锁普适性强。

2.1 CAS的关键问题:ABA问题

什么是ABA呢?当一个线程将数据A取出,经过一系列操作后把它变为B,但是最后又通过一系列操作将它变回A,那么对于另一个执行CAS操作的线程来说,可能会认为这个数据是没发生过变化的(虽然有的时候也不会出现bug),这种问题就是ABA问题。

此时,左侧的CAS中value的值不等于oldValue的值,就不执行任何操作,直接返回false。但是如果发生ABA问题,例如此时恰好有个人又给我转了500元,那么我的value又变回1000,等于oldValue,再次扣款,这就出现了很严重的bug,本来我只打算取500,但是现在取了1000!!

那又该怎么解决这个问题呢?

很简单,只需要让判定的数值按照一个方向变化即可(不要出现反复横跳,一会加一会减就可能会出现ABA问题)。在上述这个例子中,我们只需要将CAS的判定条件改为版本号,初识版本号为v1,每执行一次操作,版本号就会加1,那么,只要有其它线程穿插执行,版本号一定不等于old版本号,此时一定不会执行交换操作,而是会直接返回false,bug顺利解决。

3 信号量Semaphore

信号量是操作系统中比较重要的概念,其实信号量就是一个计数器,描述了"可用资源"的个数,每次申请一个可用资源,就要让信号量减1(P操作),每次释放一个操作,就要让信号量加1(V操作),那如果信号量已经为0的情况下继续申请资源(使用P操作)会发生什么呢?此时就会阻塞等待,直到其它线程释放一个资源(使用V操作),才能继续往下执行。

前面提到过的锁其实就是一种特殊的信号量,锁就是可用资源为1的信号量,所以一旦加锁,其它线程就会发生阻塞,因为加锁相当于使信号量减1,而此时信号量一共就是1,所以直到该线程释放锁,也就相当于执行V操作,其它线程才能获得锁

相关推荐
qq_2546744122 分钟前
Cisco Nexus 9504交换机上
java·linux·服务器
咕噜企业分发小米25 分钟前
腾讯云在多云管理工具上如何实现合规性要求?
java·云计算·腾讯云
美团测试工程师35 分钟前
软件测试面试题总结【含答案】
软件测试·面试
invicinble1 小时前
关于对后端开发工程师,在项目层面的基本需求与进阶方向
java
懒鸟一枚1 小时前
Java17新特性详解
java
戌中横1 小时前
JavaScript 对象
java·开发语言·javascript
crossaspeed1 小时前
面向对象的三大特征和反射(八股)
java·开发语言
zfj3211 小时前
java synchronized关键字用法和底层原理
java·开发语言·轻量级锁·重量级锁·偏向锁·线程同步
梵高的代码色盘1 小时前
互联网大厂Java求职面试实录与技术深度解析
java·spring·缓存·微服务·面试·互联网大厂·技术深度
E_ICEBLUE1 小时前
Excel vs CSV:在系统数据处理中该如何选择?
java·excel·csv·格式转换