Day287.其他活性故障活锁&饥饿死锁常见面试题 -Juc

Posted 阿昌喜欢吃黄桃

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Day287.其他活性故障活锁&饥饿死锁常见面试题 -Juc相关的知识,希望对你有一定的参考价值。

【一】其他活性故障

死锁是最常见的活跃性问题,不过除了之前的死锁之外,还有一些类似的问题,会导致程序无法顺利执行,统称为 活跃性问题

一、活锁

1、什么是活锁

在这里插入图片描述
在这里插入图片描述


2、代码演示

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qkAVRqYv-1622730719021)(C:/Users/PePe/AppData/Roaming/Typora/typora-user-images/image-20210603213816576.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W8tyEBeo-1622730719022)(C:/Users/PePe/AppData/Roaming/Typora/typora-user-images/image-20210603214101258.png)]


3、生产中的活锁:消息队列

  • 策略:消息如果处理失败,就放在队列开头重试

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gIZLT2HH-1622730719024)(C:/Users/PePe/AppData/Roaming/Typora/typora-user-images/image-20210603214842561.png)]


4、解决方案

增加随机因素

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


二、饥饿

1、什么是饥饿

  • 当线程需要某些资源(例如CPU),但是却一直始终得不到

  • 线程的优先级设置过低,或者有某个线程持有锁同时又无限循环从而不释放锁,或者某程序始终占用某文件的写锁


2、饥饿的影响

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mKO77Qeg-1622730719031)(C:/Users/PePe/AppData/Roaming/Typora/typora-user-images/image-20210603215525915.png)]


3、线程优先级

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JcY4Vhb8-1622730719033)(C:/Users/PePe/AppData/Roaming/Typora/typora-user-images/image-20210603215659651.png)]


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、讲一下哲学家就餐问题

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lCAV7YXk-1622730719035)(C:/Users/PePe/AppData/Roaming/Typora/typora-user-images/image-20210603222535606.png)]

解决方案

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AzZKAAzg-1622730719036)(C:/Users/PePe/AppData/Roaming/Typora/typora-user-images/image-20210603222626898.png)]


6、在实际工程中如何避免死锁

在这里插入图片描述


7、什么是活跃性问题?活锁、饥饿、死锁的区别?

以上是关于Day287.其他活性故障活锁&饥饿死锁常见面试题 -Juc的主要内容,如果未能解决你的问题,请参考以下文章

关于线程死锁,活锁和饥饿问题

死锁与活锁的区别,死锁与饥饿的区别

与死锁活锁和饥饿的哲学家一起吃饭

扫盲贴:死锁活锁饥饿

死锁与活锁的区别,死锁与饥饿的区别?

死锁与活锁的区别,死锁与饥饿的区别?