多线程:线程的活性故障

  凡是可能出错的,都会出错!——墨菲定律

  线性活性故障是由资源稀缺性或者程序自身的问题和缺陷导致线程一直处于非RUNNABLE状态,或者线程虽然处于RUNNABLE状态但是其要执行的任务却一直无法进展的故障现象。

鹬蚌相争:死锁  

  死锁是线程一种常见性故障。如果两个或者更多的线程因相互等待对面而被永远暂停(线程的生命周期状态为BLOCKED或者WAITNG),那么我们就称这些线程产生了死锁(Deadlock)。由于产生了死锁的线程的生命周期状态永远死非允许状态。因此这些线程所要执行的任务也永远无法进展。

死锁好比鹬蚌相争故事中的情形:鹬啄住蚌的肉,蚌夹住鹬的嘴,谁都不放开谁!

多线程:线程的活性故障_第1张图片

  死锁产生的必要条件,线程一旦产生死锁,那么这些线程及相关的资源将满足如下全部条件。

  1. 资源互斥(Mutual Exclusion)。涉及的资源必须是独占的,即每个资源一次只能够被一个线程使用。

  2. 资源不可掠夺(No preemption)。涉及的资源只能够被持有者(线程)主动释放。而无法被资源的持有者和申请者之外的第三方线程所抢夺(被动释放)

  3. 占用并等待资源(Hold and Wait).涉及的线程当前至少持有一个资源(资源A)并申请其他资源(资源B),而这些资源(资源B)恰好被其他线程持有。在这个资源等待的过程中,线程并不释放其已经持有的资源。

  4. 循环等待资源(Circular Wait).涉及的线程必须在等待别的线程持有的资源,而这些线程又反过来在等待第1个线程所持有的资源。

这些条件是死锁产生的必要条件而非充分条件,也就是说只要产生了死锁,那么上面这些条件一定同时成立,但是上述条件即使同时成立也不一定能产生死锁。因此死锁和其他的多线程相关的问题(比如可见性问题)类似,它并不是必然出现的!上述几个条件并非独立,其中"循环等待资源"就可能蕴含了"占用并等待资源",而"占用并等待资源"可能是"循环等待资源"的基础,但却不一定意味着"循环等待资源"。

我们可以把锁看作一种资源,这种资源正好符合"资源互斥"和"资源不可掠夺"的要求。那么,可能产生死锁的代码特征就是在持有一个锁的情况下去申请另外一个锁,这通常意味着锁的嵌套

你可能感兴趣的:(Java,程序员,线程,死锁)