怎么是死锁?
一个线程永远地持有一个锁,并且其他线程都尝试去获得这个锁时,那么它们将永远被阻塞。假如果线程A持有锁L并且想获得锁M,线程B持有锁M并且想获得锁L,那么这两个线程将永远等待下去,这种情况就是最简单的死锁形式。
死锁的必要条件
- 互斥条件:线程要求对所分配的资源进行排他性控制,即在一段时间内某 资源仅为一个进程所占有.此时若有其他进程请求该资源.则请求进程只能等待.
- 不剥夺条件:进程所获得的资源在未使用完毕之前,不能被其他进程强行夺走,即只能由获得该资源的线程自己来释放(只能是主动释放).
- 请求和保持条件:线程已经保持了至少一个资源,但又提出了新的资源请求,而该资源已被其他线程占有,此时请求线程被阻塞,但对自己已获得的资源保持不放.
- 循环等待条件:存在一种线程资源的循环等待链,链中每一个线程已获得的资源同时被链中下一个线程所请求
代码示例:
class TTT extends Thread {
private Integer p1 = null;
private Integer p2 = null;
private String name = null;
public TTT(Integer p1, Integer p2, String name) {
this.p1 = p1;
this.p2 = p2;
this.name = name;
}
public void run() {
try {
if ("路飞".equals (this.name)) {
synchronized (p1) {
Thread.sleep (1);
synchronized (p2) {
}
}
} else {
synchronized (p2) {
Thread.sleep (1);
synchronized (p1) {
}
}
}
} catch (InterruptedException e) {
e.printStackTrace ();
}
}
}
public class 死锁 {
public static void main(String[] args) {
Integer p1 = 10;
Integer p2 = 22;
TTT t1 = new TTT (p1, p2, "路飞");
TTT t2 = new TTT (p1, p2, "娜美");
}
}
输出:
可以看到,因为死锁的缘故,线程没有执行。
解决死锁
线程每次只锁定一个对象并且在锁定该对象的过程中不再去锁定其他的对象,这样就不会导致死锁了
参考文字:https://www.jb51.net/article/126410.htm