【摘要】:动手写16.7.2中,我们尝试改变ThreadB中Lock2和Lock1锁的先后顺序,再看一下死锁情况是否还会发生。动手写16.7.2上面示例的程序会执行完成,并不会发生死锁,其运行结果为:图16.7.2死锁解决不幸的是,Java并没有对死锁提供语言层面的支持,只能通过仔细的设计程序来避免这种现象发生。
死锁
一个对象可以使用synchronized方法或其他形式的加锁机制,让任务进入阻塞状态,此时会出现一种情况:一个任务在等待另一个任务,后者又在等待别的任务,不断循环下去,直到这条链路上的任务又在等待第一个任务释放锁。这时所有线程任务都无法继续执行,全都在等待任务解锁中不断地循环下去,令程序进入死循环,也就是死锁。
动手写16.7.1
上面示例在执行时会发生死锁,程序将永远挂起,两个线程都不能继续执行,一直在等待互相释放锁,其运行结果为:
图16.7.1 两个线程发生死锁
死锁并不一定只出现在两个线程间,多个线程之间也会出现互相等待的情况从而发生死锁。出现死锁的几种条件如下所示:
1.互斥条件。任务使用的资源中至少有一个是不能共享的。
2.至少有一个任务必须持有一个资源且正在等待获取一个当前被别的任务持有的资源。(www.xing528.com)
3.资源不能被任务抢占,任务必须把资源释放当作普通事件。
4.必须有循环等待。
当这些条件都满足时,就会发生死锁,因此解决死锁的方法就是破坏这四个条件中的任意一个。一般情况下,会避免出现有循环等待的情况,从而避免死锁的情况发生。动手写16.7.2中,我们尝试改变ThreadB中Lock2和Lock1锁的先后顺序,再看一下死锁情况是否还会发生。
动手写16.7.2
上面示例的程序会执行完成,并不会发生死锁,其运行结果为:
图16.7.2 死锁解决
不幸的是,Java并没有对死锁提供语言层面的支持,只能通过仔细的设计程序来避免这种现象发生。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。