死锁(二十四)
死锁(二十四)
什么是死锁
死锁指的是两个线程分别获取对方手上的资源,导致两个线程都阻塞,程序卡死的情况。就好比有两个玩具,两个小孩人手一个,这时两个小孩都想要对方手上的玩具;当然,作为人我们可以相互交换,但是计算器没有这么聪明,就相互卡死了。
package com.unsafe;
public class DeathLock {
public static void main(String[] args) {
Kid kid1 = new Kid("小明", 1);
Kid kid2 = new Kid("小红", 0);
new Thread(kid1).start();
new Thread(kid2).start();
}
}
class Flight {}
class Train {}
class Kid implements Runnable{
static final Flight flight = new Flight();
static final Train train = new Train();
String name;
int choice;
public Kid(String name, int choice) {
this.name = name;
this.choice = choice;
}
@Override
public void run() {
if (choice==1) {
synchronized (flight) {
System.out.println(this.name+"拿到了flight");
synchronized (train) {
System.out.println(this.name+"拿到了train");
}
}
} else {
synchronized (train) {
System.out.println(this.name+"拿到了train");
synchronized (flight) {
System.out.println(this.name+"拿到了flight");
}
}
}
}
}
我们可以看到,小明和小红两个小朋友,分别拿了飞机和火车的玩具,都想要拿对方手上的玩具,这时就造成了死锁,运行结果如下,程序就这么卡住,无法继续往下走了。
小明拿到了flight
小红拿到了train
产生死锁的必要条件
- 互斥条件:进程要求对所分配的资源进行排它性控制,即在一段时间内某资源仅为一进程所占用。
- 请求和保持条件:当进程因请求资源而阻塞时,对已获得的资源保持不放。
- 不剥夺条件:进程已获得的资源在未使用完之前,不能剥夺,只能在使用完时由自己释放。
- 环路等待条件:在发生死锁时,必然存在一个进程--资源的环形链。
避免死锁
避免死锁我们只需要打破上面四个条件中的一个即可,那么我们要怎样避免这种死锁的情况呢?上面的例子中,我们只要在获取对方的玩具的时候,先放下自己手上的玩具就行啦,看下面的代码。
package com.unsafe;
public class DeathLock {
public static void main(String[] args) {
Kid kid1 = new Kid("小明", 1);
Kid kid2 = new Kid("小红", 0);
new Thread(kid1).start();
new Thread(kid2).start();
}
}
class Flight {}
class Train {}
class Kid implements Runnable{
static final Flight flight = new Flight();
static final Train train = new Train();
String name;
int choice;
public Kid(String name, int choice) {
this.name = name;
this.choice = choice;
}
@Override
public void run() {
if (choice==1) {
synchronized (flight) {
System.out.println(this.name+"拿到了flight");
}
synchronized (train) {
System.out.println(this.name+"拿到了train");
}
} else {
synchronized (train) {
System.out.println(this.name+"拿到了train");
}
synchronized (flight) {
System.out.println(this.name+"拿到了flight");
}
}
}
}
这次我们来看结果,可以这场运行啦
小明拿到了flight
小红拿到了train
小红拿到了flight
小明拿到了train
Process finished with exit code 0