您的位置:首页 > 编程语言 > Java开发

Java 并发编程深入学习(五)——死锁

2016-09-05 10:35 363 查看

死锁介绍

  在Java中,一个对象可以有synchronized方法或别的加锁机制来防止别的任务在互斥还没有释放的时候就访问这个对象。线程是可以阻塞的,某个线程在等待另一个线程,而后者又在等待别的线程,这样一直下去,直到这个链条上的线程又在等待第一个线程释放锁。这就造成了线程之间相互等待的连续循环,没有哪个线程能够继续,这被称之为死锁。

产生条件

  死锁的发生必须具备以下四个必要条件(此处描述不区分线程和进程概念,实际情况下所有的死锁情况都必须具备这四个条件):

互斥条件:指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。如果此时还有其它进程请求资源,则请求者只能等待,直至占有资源的进程用毕释放。

请求和保持条件:指进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放。

不剥夺条件:指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。

环路等待条件:指在发生死锁时,必然存在一个进程——资源的环形链,即进程集合{P0,P1,P2,···,Pn}中的P0正在等待一个P1占用的资源;P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源。

下面的例子展示了一个死锁发生的情形:

线程A当前持有互斥所锁lock1,线程B当前持有互斥锁lock2。接下来,当线程A仍然持有lock1时,它试图获取lock2,因为线程B正持有lock2,因此线程A会阻塞等待线程B对lock2的释放。如果此时线程B在持有lock2的时候,也在试图获取lock1,因为线程A正持有lock1,因此线程B会阻塞等待A对lock1的释放。二者都在等待对方所持有锁的释放,而二者却又都没释放自己所持有的锁,这时二者便会一直阻塞下去。

代码如下:

public class TestDeadLock {
public static void main(String[] args) {

Object o1 = new Object();
Object o2 = new Object();

MyThread ta = new MyThread(o1, o2);
MyThread tb = new MyThread(o2, o1);
ta.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
tb.start();

}
}

class MyThread extends Thread {
private Object lock1;
private Object lock2;

public MyThread(Object lock1, Object lock2) {
this.lock1 = lock1;
this.lock2 = lock2;
}

@Override
public void run() {
synchronized (lock1) {
System.out.println(Thread.currentThread().getName() + "取得锁1");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock2) {
System.out.println(Thread.currentThread().getName() + "取得锁2");
}
}
System.out.println(Thread.currentThread().getName() + "执行结束");
}
}


运行结果:

Thread-0取得锁1
Thread-1取得锁1


从结果中可以看出,由于两个线程都在试图获取对方的所持有的对象锁,但对方都没有释放自己持有的对象锁,因而便产生了死锁,程序将无法继续执行。

避免死锁

  大部分代码并不容易产生死锁,死锁可能在代码中隐藏相当长的时间,等待不常见的条件地发生,但即使是很小的概率,一旦发生,便可能造成毁灭性的破坏。避免死锁是一件困难的事,遵循以下原则有助于规避死锁:

只在必要的最短时间内持有锁,考虑使用同步语句块代替整个同步方法;

尽量编写不在同一时刻需要持有多个锁的代码,如果不可避免,则确保线程持有第二个锁的时间尽量短暂;

创建和使用一个大锁来代替若干小锁,并把这个锁用于互斥,而不是用作单个对象的对象级别锁;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: