进阶面试题
- 一. 锁拓展
- 1.1 乐观锁与悲观锁
- 1.2 轻量级锁与重量级锁
- 1.3 自旋锁和挂起等待锁
- 1.4 普通互斥锁与读写锁
- 1.5 公平锁与非公平锁
- 1.6 可重入锁和不可重入锁
- 二.锁的优化策略
- 2.1 锁的自适应
- 2.2 锁消除
- 2.3 锁粗化
- 三.CAS
一. 锁拓展
1.1 乐观锁与悲观锁
乐观锁 : 加锁前,预估产生锁冲突的概率不大,在加锁的过程中不会做太多工作, 加锁的速度快, 但是会消耗很多的CPU资源.
悲观锁 : 加锁前, 预估产生所冲突的概率较大,在加锁的过程中做很多工作,加锁的速度慢.整个过程中不易产生其他问题,
1.2 轻量级锁与重量级锁
轻量级锁 : 加锁的开销小, 加锁的速度快 同时也是乐观锁
重量级锁: 加锁的开销大, 加锁的速度慢
1.3 自旋锁和挂起等待锁
自旋锁 : 加锁的时候,有一个while循环,加锁成功,循环结束, 如果不成功, 一直循环,再次尝试获取到锁 是一种乐观锁
挂起等待锁: 直接放弃争夺CPU. 是一种重量级锁, 也是悲观锁.
1.4 普通互斥锁与读写锁
普通互斥锁 : 类似于 synchronized锁
读写锁 : 分为加读锁 和 加写锁
读锁和读锁之间不会发生所冲突 读锁和写锁 写锁和写锁之间会发生锁冲突
简而言之就是 一个线程在读的时候,另一个线程只能读 不能写
一个线程在写的时候 另一个线程 不能读 也不能写
1.5 公平锁与非公平锁
公平锁 : 在发明公平锁的人的角度讲, 要遵守先来后到 才是公平
非公平锁
1.6 可重入锁和不可重入锁
可重入锁 : 一个线程,连续对同一个锁对象加锁两次,而不会产生死锁
不可重入锁 : 会产生死锁
二.锁的优化策略
2.1 锁的自适应
偏向锁 ------ 轻量级锁 -------- 重量级锁
偏向锁阶段 : 类似于懒汉模式, 能晚加锁就晚加锁 能不加锁就不加锁 , 偏向锁不是真正加锁, 而是加上一个轻量级的标记 , 一旦有线程来竞争锁, 就会升级到轻量级锁阶段, 偏向锁在没有锁竞争的时候效率极高,
轻量级锁阶段 : 通过自旋锁的方式来实现, 在第一时间检测到有线程释放锁, 就会第一时间拿到锁 缺点: 消耗CPU资源 , 当发现竞争锁的线程增多的时候,就会升级到重量级锁
重量级锁阶段 : 拿不到锁的线程不会自旋, 而是 挂起等待 , 主动让出CPU资源
2.2 锁消除
编译器发现 没有涉及到线程安全问题的代码 就会直接把锁消除.
2.3 锁粗化
把多个细粒度的锁 合成 一个 粗粒度的锁
所谓的细粒度和粗粒度, synchronized 大括号内的代码越多, 粒度越粗
三.CAS
CAS 称为 compare and swap 比较并交换
有两个寄存器的值, 用一个寄存器中的值和内存中的值比较
如果相等 , 就交换内存的值和另一个寄存器中的值
如果不相同 return false