聊聊死锁(二)

72 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 15 天,点击查看活动详情

上一篇文章 聊聊死锁 (一) ,我们学习了死锁的必要条件:互斥条件、不可剥夺条件、请求与保持条件、循环等待条件,今天,我们来一起看看如何预防死锁吧!

发生死锁时,必然会存在死锁的四个必要条件。也就是说,如果我们在写程序时,只要“破坏”死锁的四个必要条件中的一个,就能够避免死锁的发生。接下来,我们就一起来探讨下如何“破坏”这四个必要条件。

破坏互斥条件

我们使用锁为的就是线程之间的互斥,互斥条件是我们没办法破坏的。

破坏不可剥夺条件

破坏不可剥夺的条件的核心就是让当前线程自己主动释放占有的资源,关于这一点,synchronized 是做不到的,我们可以使用 java.util.concurrent 包下的 Lock 来解决。

image.png

破坏请求与保持条件

破坏请求与保持条件,我们可以一次性申请所需要的所有资源:如图所示:

  • 一次申请所有的资源和释放所有资源的代码:

image.png

  • 此时,转账类的代码就变成了:

image.png

破坏循环等待条件

破坏循环等待条件,则可以通过对资源排序,按照一定的顺序来申请资源,然后按照顺序来锁定资源,可以有效的避免死锁。代码的实现方式如图所示:

image.png

总结

在并发编程中,使用细粒度锁来锁定多个资源时,要时刻注意死锁的问题。另外,避免死锁最简单的方法就是阻止循环等待条件,将系统中所有的资源设置标志位、排序,规定所有的线程申请资源必须以一定的顺序来操作进而避免死锁。