如果两个线程在运行中都在等待对方的锁,那么这两个线程都将处于无限期的阻塞状态,程序不可能正常终止,这种现象被称为死锁。
死锁产生的四个必要条件:
(1)互斥使用,即当资源被一个线程使用(占有)时,别的线程不能使用。
(2)不可抢占,资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放。
(3)请求和保持,即当资源请求者在请求其他的资源的同时保持对原有资源的占有。
(4)循环等待,即存在一个等待队列:P1占有P2的资源,P2占有P3的资源,P3占有P1的资源。这样就形成了一个等待环路。
当上述四个条件都成立的时候,便形成死锁。当然,在死锁的情况下,如果打破上述任何一个条件,便可让死锁消失。
【例6-9】
死锁场景演示。
下面通过一个案例来演示产生死锁的情形。
步骤1:在chapter6工程src文件夹下新建一个包cn.linaw.chapter6.demo07,然后将cn.linaw.chapter6.demo06包里的MySyn Locks.java拷贝过来。(www.xing528.com)
步骤2:定义一个任务类Task A。线程执行体先申请MySyn Locks.lock1锁,进入MySyn Locks.lock1锁同步代码块,在持有该锁的情况下,继续申请MySyn Locks.lock2锁,进入MySyn Locks.lock2锁同步代码块。为了更好地产生死锁,当申请到MySyn Locks.lock1锁后,调用Thread.yield()方法让出线程CPU使用权,如图6-24所示。
图6-24 任务类Task A
步骤3:定义一个任务类Task B,线程执行体先申请MySyn Locks.lock2锁,在持有该锁的情况下,继续申请MySyn Locks.lock1锁,如图6-25所示。
图6-25 任务类TaskB
步骤4:定义一个测试类Dead Lock Test验证,如图6-26所示。
图6-26 程序发生死锁
结果显示,程序运行便发生了死锁。死锁发生时,多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止,只能手动强制退出。在进行多线程开发时,需要仔细分析,避免死锁的发生。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。