死锁
死锁是这样一种情形:多个线程同时被阻塞,它们中的一个或者所有都在等待某个资源被释放。因为线程被无限期地阻塞,所以程序不可能正常终止。
致使死锁的根源在于不适当地运用“synchronized”关键词来管理线程对特定对象的访问。“synchronized”关键词的做用是,确保在某个时刻只有一个线程被容许执行特定的代码块,所以,被容许执行的线程首先必须拥有对变量或对象的排他性的访问权。当线程访问对象时,线程会给对象加锁,而这个锁致使其它也想访问同一对象的线程被阻塞,直至第一个线程释放它加在对象上的锁。
因为这个缘由,在使用“synchronized”关键词时,很容易出现两个线程互相等待对方作出某个动做的情形。代码一是一个致使死锁的简单例子。
//代码一 多线程
1 class Deadlocker { 2 int field_1; 3 private Object lock_1 = new int[1]; 4 int field_2; 5 private Object lock_2 = new int[1]; 6 7 public void method1(int value) { 8 “synchronized” (lock_1) { 9 “synchronized” (lock_2) { 10 field_1 = 0; field_2 = 0; 11 } 12 } 13 } 14 15 public void method2(int value) { 16 “synchronized” (lock_2) { 17 “synchronized” (lock_1) { 18 field_1 = 0; field_2 = 0; 19 } 20 } 21 } 22 } 23
参考代码一,考虑下面的过程:
◆ 一个线程(ThreadA)调用method1()。
◆ ThreadA在lock_1上同步,但容许被抢先执行。
◆ 另外一个线程(ThreadB)开始执行。
◆ ThreadB调用method2()。
◆ ThreadB得到lock_2,继续执行,企图得到lock_1。但ThreadB不能得到lock_1,由于ThreadA占有lock_1。
◆ 如今,ThreadB阻塞,由于它在等待ThreadA释放lock_1。
◆ 如今轮到ThreadA继续执行。ThreadA试图得到lock_2,但不能成功,由于lock_2已经被ThreadB占有了。
◆ ThreadA和ThreadB都被阻塞,程序死锁。
固然,大多数的死锁不会这么显而易见,须要仔细分析代码才能看出,对于规模较大的多线程程序来讲尤为如此。好的线程分析工具,例如JProbe Threadalyzer可以分析死锁并指出产生问题的代码位置。 工具