因为线程可以变为阻塞,且因为对象可以拥有互斥锁,这些锁能够阻止线程在锁被释放之前访问这个对象。所以就有可能出现这种情况,某个线程在等待另一个线程而第2个线程又在等待别的线程,以此类推,直到这个链上的最后一个线程回头等待第1个线程。这样就会得到一个由互相等待的线程构成的连续的循环,而使任何线程都不能运行——死锁。死锁的过程是很难重现的,调试的难点。
下面看一个经典的死锁问题——哲学家聚餐。

如果在某一个时间点上所有的哲学家同时试图进餐,拿起同一侧的一根筷子,并且等待紧挨着他们的哲学家放下筷子,这样程序将会死锁。
同时满足以下4种条件,死锁就会发生:
1、相互排斥。线程使用的资源至少有一个必须是不可共享的。在这种情况下,一根筷子一次只能被一个哲学家使用。
2、至少有一个线程必须持有某一种资源,并且同时等待获得正在被另外的线程所持有的资源。也就是说要发生死锁一个哲学家必须持有一根筷子并且等待另一根筷子。
3、不能以抢占的方式剥夺一个线程的资源。所有线程只能把释放的资源作为一个正常事件。他们不会从别的哲学家手中抢夺筷子。
4、出一个循环等待。一个线程等待另外的线程所持有的资源,而这个等待的线程又等待另一个线程所持有的资源,以此类推直到某个线程去等待第一个线程所持有的资源。例子中每一个哲学家总是试图先得到右边的筷子,而后得到左边的筷子,所以发生了循环等待。
避免死锁只要打破以上四个条件中的一个就可以了!
本文通过哲学家就餐问题,深入浅出地介绍了死锁的概念及产生的四个必要条件,并提供了一个简单的代码示例来展示如何打破循环等待条件以避免死锁。
——死锁&spm=1001.2101.3001.5002&articleId=6458000&d=1&t=3&u=bf48948cca844eb8a170f0d155a277a7)
2366

被折叠的 条评论
为什么被折叠?



