鹬蚌相争:死锁
死锁是一种常见的活性故障,如果两个或者更多的线程因相互等待对方而被永远暂停(生命周期为BLOCKED或者WAITING),那么就称这鞋线程产生了死锁。
多线程产生死锁的四个必要条件:
1、互斥条件:任意时刻一个资源只能给一个进程使用,其他进程若申请一个资源,而该资源被另一进程占有时,则申请
者等待直到资源被占有者释放。
2、不可剥夺条件:进程所获得的资源在未使用完毕之前,不被其他进程强行剥夺,而只能由获得该资源的进程资源释放。
3、请求和保持条件:进程每次申请它所需要的一部分资源,在申请新的资源的同时,继续占用已分配到的资源。
4、循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
巧妇难为无米之炊: 线程饥饿
线程饥饿( Thread Starvation )是指线程一直无法获取其所需的资源而导致其任务无法进展的一种活性故障。
线程饥饿的一个典型例子是在高争用的环境下使用非公平模式(Non-fir mnde )的读写锁(ReentrantReadWriteLock)。 例如,在Web应用程序中使用ReentrantReadWriteLocok读写锁来保护配置数据, 业务线程可能不断地申请读写锁的读锁来读取配置数据,由于默认情改下ReCcaraeWreteLroe的锁调度采用非公平调度模式,因此如果这些业务线程对锁合争用程星度比较高,那么系统管理模块试图更新配置数据的时候就可能遇到这样的情形:相应的读锁锁总是被业务线程抢先占有(非公平锁调度可能导致的结果)导致系统管理模块线程始终无法获得相应的写锁,从而使其一直无法更新配置数据。 因此,尽管非公平锁支持更高的吞吐率,但是它也可能导致某些线程总是无法获取其所需的资源(锁),导致线程饥饿。
把锁看作一种资源,那么我们不难发现死锁也是一种线程饥饿。死锁的结果是故障线程都无法获得其所需的全部锁中的一个锁,从而使其任务一直无法进展, 这相当于线法获得其所需的全部资源(锁)而使得其任务一 直无法进展,即产生了线程饥饿。由程饥饿的产生条件是一个(或者多个)线程始终无法获取其所需的资源,显然这个条满足并不意味着死锁产生的必要条件(这还仅是必要条件,而不是充分条件)的满足此线程饥饿并不会导致死锁。
线程饥饿涉及的线程,其生命周期状态不一定就是 WATING或者BLOCKED其伏态也可能是RUNNING (这说明涉及的线程直在电请其所需的资源), 这时演变成活锁。
屡战屡败, 屡败屡战:活锁
活锁( Livelock )是指线程一直处于运行状态, 但是其任务却一直无法进展的性战体,也就是说,产生活锁的线程一直在做无用功,这就好比小猫咬自己的尾巴,虽然一直在咬,但是却直咬不到自己的尾巴。