简介
两个及以上的线程, 因资源争夺无法继续执行。
四个必要条件
- 互斥: 在相同时间下, 资源只能被一个进程所持有。
- 不剥夺: 资源只能被线程主动释放, 不可被抢夺。
- 请求和保持: 线程请求已被其他线程持有的资源, 无法获取,进入等待模式,且自身持有资源不释放。
- 循环等待: 存在一种线程资源的循环等待链,链中每一个线程已获得的资源同时被链中下一个进程所请求。
原因
-
资源争夺
不可剥夺的资源,不足以满足多线程需要, 使得线程间相互争夺而陷入僵局。 -
推进顺序非法
进程在运行过程中,释放和请求资源的顺序不当,也同样会导致死锁。
如何避免死锁
- 锁持有顺序
- 锁超时策略
- 主动检测死锁
示例代码
public class LockDemo {
private static Object lockA = new Object();
private static Object lockB = new Object();
public static void main(String[] args) {
new Thread(new Runnable() {
public void run() {
while(true) {
methodB();
try{
Thread.sleep(300);
} catch (Exception e) {}
}
}
}).start();
new Thread(new Runnable() {
public void run() {
while(true) {
methodA();
try{
Thread.sleep(300);
} catch (Exception e) {}
}
}
}).start();
}
public static void methodA() {
synchronized(lockA) {
synchronized(lockB) {
System.out.println("methodA");
}
}
}
public static void methodB() {
synchronized(lockB) {
synchronized(lockA) {
System.out.println("methodB");
}
}
}
public static void methodC() {
synchronized(lockA) {
synchronized(lockB) {
System.out.println("methodC");
}
}
}
public static void methodD() {
synchronized(lockA) {
synchronized(lockB) {
System.out.println("methodD");
}
}
}
}