跳到主要内容

Java并发编程学习十二:死锁问题

一、死锁的产生

想要产生死锁,必须同时满足4个必要条件:

  • 互斥条件:每个资源每次只能被一个线程(或进程,下同)使用。否则,如果每个人都可以拿到想要的资源,那就不需要等待,所以是不可能发生死锁的
  • 请求保持条件:当一个线程因请求资源而阻塞时,则需对已获得的资源保持不放。否则,在请求资源时阻塞后自动释放手中资源(例如锁)的话,其他线程获取到其他的资源,就不会形成死锁
  • 不剥夺条件:线程已获得的资源,在未使用完之前,不会被强行剥夺。否则,其他线程可以强行获取资源,同样不会形成死锁
  • 循环等待条件:若干线程之间形成一种头尾相接的循环等待资源关系时,才有可能形成死锁。如两个线程互相持有对方所需要的资源,三个及以上的线程形成环路,依次请求下一个线程已经持有的资源

下面是一个必然会发生死锁的案例:

/**
* 描述: 必定死锁的情况
*/
public class MustDeadLock implements Runnable {



public int flag;
static Object o1 = new Object();
static Object o2 = new Object();

public void run() {


System.out.println("线程"+Thread.currentThread().getName() + "的flag为" + flag);
if (flag == 1) {


synchronized (o1) {


try {


Thread.sleep(500);
} catch (Exception e) {


e.printStackTrace();
}
synchronized (o2) {


System.out.println("线程1获得了两把锁");
}
}
}
if (flag == 2) {


synchronized (o2) {


try {


Thread.sleep(500);
} catch (Exception e) {


e.printStackTrace();
}
synchronized (o1) {


System.out.println("线程2获得了两把锁");
}
}
}
}

public static void main(String[] argv) {


MustDeadLock r1 = new MustDeadLock();
MustDeadLock r2 = new MustDeadLock();
r1.flag = 1;
r2.flag = 2;
Thread t1 = new Thread(r1, "t1");
Thread t2 = new Thread(r2, "t2");
t1.start();
t2.start();
}
}