Day287.其他活性故障活锁&饥饿死锁常见面试题 -Juc
Posted 阿昌喜欢吃黄桃
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Day287.其他活性故障活锁&饥饿死锁常见面试题 -Juc相关的知识,希望对你有一定的参考价值。
【一】其他活性故障
死锁是最常见的活跃性问题,不过除了之前的死锁之外,还有一些类似的问题,会导致程序无法顺利执行,统称为 活跃性问题
一、活锁
1、什么是活锁
2、代码演示
3、生产中的活锁:消息队列
- 策略:消息如果处理失败,就放在队列开头
重试
4、解决方案
增加随机因素
二、饥饿
1、什么是饥饿
-
当线程需要某些资源(例如CPU),但是却一直
始终得不到
-
线程的
优先级
设置过低,或者有某个线程持有锁同时又无限循环从而不释放锁
,或者某程序始终占用
某文件的写锁
2、饥饿的影响
3、线程优先级
4、解决方案
- 注意到程序上不应该有对于锁使用完不释放的逻辑错误
- 不应该在程序中设置优先级
【二】死锁常见面试问题
1、写一个必然死锁的例子,生产中什么场景下会发送死锁?
/******
@author 阿昌
@create 2021-05-31 21:16
*******
* 必定发生死锁的情况
*/
public class MustDeadLock implements Runnable {
int flag = 1;//标记位
static Object lock1 = new Object();
static Object lock2 = new Object();
public static void main(String[] args) {
MustDeadLock r1 = new MustDeadLock();
MustDeadLock r2 = new MustDeadLock();
r1.flag=1;
r2.flag=0;
Thread thread1 = new Thread(r1);
Thread thread2 = new Thread(r2);
thread1.start();
thread2.start();
}
@Override
public void run() {
System.out.println("flag= " + flag);
if (flag == 1) {
synchronized (lock1){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock2){
System.out.println(flag);
}
}
}
if (flag == 0) {
synchronized (lock2){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock1){
System.out.println(flag);
}
}
}
}
}
;
-
在一个方法中获取多个锁,容易发生死锁
-
出现在一个方法中获取一个锁,然后在另一个方法中获取另一个锁,以此类推,出现锁的循环链路
2、死锁发生必然满足的条件
- 互斥条件
锁资源只能同时被一个线程拿到
- 请求与保持条件
手里有一个锁,再去请求另一个锁,且不放弃手上的锁
- 不剥夺条件
线程拥有锁,但不被第三方剥夺直接抢走锁
- 循环等待条件
在多个线程中,构成环路
3、如何定位死锁?
- jstack
- ThreadMXBean类
4、解决死锁问题的策略
- 避免策略
哲学家换手、转账换序
- 检测与恢复
一段时间内检测是否有死锁,如果有就剥夺某个资源,来打开死锁
- 鸵鸟策略
忽略死锁,直到发生死锁后,人工干预修复
5、讲一下哲学家就餐问题
解决方案:
6、在实际工程中如何避免死锁
7、什么是活跃性问题?活锁、饥饿、死锁的区别?
以上是关于Day287.其他活性故障活锁&饥饿死锁常见面试题 -Juc的主要内容,如果未能解决你的问题,请参考以下文章