快速了解死锁及如何解决死锁问题

目录

什么是死锁?

死锁代码示例

产生死锁的条件:

死锁的危害:

如何解决死锁问题?

1、预防死锁(破坏上述4个产生死锁的条件):

2、银行家算法

3、死锁的检测、解除

4、采用超时机制


什么是死锁?

线程1获取了资源A并且不释放,线程2获取了资源B不释放。此时线程1要获取资源B,线程1等待线程2释放资源,但同时线程2要获取资源A,等待线程1释放资源。此时,线程1和2都等待对方释放资源,线程永远执行了下去,不释放资源。这种情况就是死锁。

死锁代码示例

public class DeadlockTest {
    private static final Object lock1 = new Object();
    private static final Object lock2 = new Object();

    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            synchronized (lock1) {
                System.out.println("Thread1 获得 lock1");
                try {
                    Thread.sleep(1000);//暂停一秒
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (lock2) {
                    System.out.println("Thread1 获得 lock2");
                }
            }
        });

        Thread t2 = new Thread(() -> {
            synchronized (lock2) {
                System.out.println("Thread2 获得 lock2");
                try {
                    Thread.sleep(1000);//暂停一秒
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (lock1) {
                    System.out.println("Thread2 获得 lock1");
                }
            }
        });

        t1.start();
        t2.start();
    }
}

通过人为的设置睡眠一秒,产生死锁。

产生死锁的条件:

1.互斥条件:资源不能共享(仅由一个线程使用)
2.请求和保持条件:一个线程已经保持至少一个资源,并请求获得其他线程正在使用的资源。
3.不剥夺条件:线程已获得的资源,在未使用完之前,不能被其它线程强行获取,只能等它自己释放。
4.循环等待条件:线程等待其它线程释放,形成一种闭环等待的现象(闭环:A等B,B等C,C等...,Z等A)

死锁的危害:

一直占用资源,造成资源的浪费;死锁的线程无法继续执行,一直在等待,会影响系统的整体性能;特殊情况下还可能导致系统变得无法响应。

如何解决死锁问题?

1、预防死锁(破坏上述4个产生死锁的条件):

破坏互斥条件:把资源设置为共享的。
破坏请求和保持条件:一次性分配所有线程所需的全部资源。
破坏不可剥夺条件:允许线程在使用资源的过程中被强制中断并释放资源。
破坏循环等待条件:提前对资源编号,然后按序分配。

2、银行家算法

系统预先声明每个线程最大需要的资源数量。然后动态跟踪已分配和可用资源,判断是否存在安全序列。如果存在安全序列,则分配资源,否则暂缓分配。

3、死锁的检测、解除

定期检测系统中是否存在死锁,一旦发现死锁,采取措施主动解除(如撤销部分线程)

4、采用超时机制

对长时间请求资源的线程进行超时处理,防止请求无限期地被阻塞。(需要自行设置合理的超时时间:如果超时时间过短,可能会导致大量的请求被终止,影响系统性能;如果超时时间过长,无法及时发现并解决死锁问题)

风险相对其它方法较大,对于一些关键的长时间运行的任务,被终止可能会造成无法挽回的严重后果。

相关推荐

  1. 解决Oracle问题

    2024-07-21 09:32:02       27 阅读
  2. 以及如何避免

    2024-07-21 09:32:02       31 阅读
  3. 资源、如何监测

    2024-07-21 09:32:02       32 阅读
  4. 2024-07-21 09:32:02       40 阅读
  5. 问题,4个必要条件+避免

    2024-07-21 09:32:02       62 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-21 09:32:02       52 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-21 09:32:02       54 阅读
  3. 在Django里面运行非项目文件

    2024-07-21 09:32:02       45 阅读
  4. Python语言-面向对象

    2024-07-21 09:32:02       55 阅读

热门阅读

  1. git clone/push报错:HTTP Basic: Access denied

    2024-07-21 09:32:02       17 阅读
  2. 高等数学用到的初等数学

    2024-07-21 09:32:02       16 阅读
  3. JVM 在什么情况下会触发垃圾回收?

    2024-07-21 09:32:02       15 阅读
  4. Dubbo 的本地伪装

    2024-07-21 09:32:02       18 阅读
  5. 服务器注意事项

    2024-07-21 09:32:02       16 阅读
  6. 强化学习算法PPO实现

    2024-07-21 09:32:02       12 阅读
  7. ansible——ansible的安装

    2024-07-21 09:32:02       16 阅读
  8. Kotlin 基础语法

    2024-07-21 09:32:02       18 阅读
  9. OpenSSH移植

    2024-07-21 09:32:02       13 阅读
  10. MySQL 创建数据库

    2024-07-21 09:32:02       15 阅读
  11. python的lambda匿名函数

    2024-07-21 09:32:02       18 阅读
  12. R9000X安装ubuntu后没有声音问题解决

    2024-07-21 09:32:02       16 阅读
  13. 【SpringBoot】测试Control接口方法

    2024-07-21 09:32:02       17 阅读
  14. Vit配置

    2024-07-21 09:32:02       19 阅读
  15. Tracy 小笔记:微信小程序 mpx 雷达图的实现

    2024-07-21 09:32:02       15 阅读