一、线程产生死锁的原因
举个例子来说明。帅哥请美女到家里去吃烛光晚餐,浪漫的小伙子准备了西餐,可是家里只有一副刀叉。帅哥拿了刀还想要叉,美女拿了叉还想要刀。于是两人大眼瞪小眼,谁也不让,最后双双饿死在餐桌上~~~
这就像线程死锁。一个线程占有了资源A,它还想同时占有资源B。而另一个线程占有了资源B,又想占有资源A,两者互不想让,最终双双阻塞。
二、为什么会产生死锁
1.因为系统资源不足。
2.进程运行推进的顺序不合适。
3.资源分配不当。
三、产生死锁的四个必要条件
1.互斥条件:一个资源每次只能被一个进程使用。
2.请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
3.不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
4.循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
三、例程
借用一个经典的例子来说明:
package cn.thread;
/**
* 线程死锁
*
* @author 林计钦
* @version 1.0 2013-7-24 上午10:42:20
*/
public class ThreadDieSock implements Runnable {
private int flag = 1;
private Object obj1 = new Object(), obj2 = new Object();
public void run() {
System.out.println("flag=" + flag);
if (flag == 1) {
synchronized (obj1) {
System.out.println("我已经锁定obj1,休息0.5秒后锁定obj2去!");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (obj2) {
System.out.println("1");
}
}
}
if (flag == 0) {
synchronized (obj2) {
System.out.println("我已经锁定obj2,休息0.5秒后锁定obj1去!");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (obj1) {
System.out.println("0");
}
}
}
}
public static void main(String[] args) {
ThreadDieSock run01 = new ThreadDieSock();
ThreadDieSock run02 = new ThreadDieSock();
run01.flag = 1;
run02.flag = 0;
Thread thread01 = new Thread(run01);
Thread thread02 = new Thread(run02);
System.out.println("线程开始喽!");
thread01.start();
thread02.start();
}
}
运行结果如下: