和人们所说的一样,线程死锁的解决方式就是破坏线程死锁的的产生条件,上一篇文章说到
1 互斥条件 线程使用的资源必须至少有一个是不能共享的
2 请求与保持条件 至少有一个线程必须持有一个资源并且正在等待获取一个当前被其他线程持有的资源。
4 循环等待条件 第一个线程等待其他线程,后者又在等待第一个线程。
这里介绍一种避免死锁的方式 我们为所有的线程用户规定一个次序,线程用户必须要按照次序来调用资源,这样就可以避免纠纷
上一章我们讲到吃饭问题 我们还是以这个问题作为例子
有一碗饭和一双筷子(饭足够两个人吃,这里我们忽略掉卫生的问题)
显然,同一时刻只能有一个人在吃饭
这里有两个人要吃饭,一个叫Tom 一个叫做Jerry,并且Tom享有优先吃饭权
Jerry必须要等到Tom吃完饭才能吃饭
这里我们用while死循环来模拟一个循环等待的过程,当吃饭的任务完成我们才终止这个循环
为了使整个过程更加直观我们使用线程睡眠来模拟吃饭的过程,不然运行太快了不好模拟
Rice -- 1 时tom获取饭 Rice - 2时Tom获取筷子
Chopsticks -- 1 时Jerry获取饭 Chopsticks- 2时Jerry获取筷子
两个变量的默认值都是1 表示Tom拥有优先吃饭的权利
当Tom吃完饭将两个值都设置为2 用来通知Jerry吃饭
/**
* 1. we supposed that tom has high priority to eat meal
* 2. when rice is 1,tom can get it, else jerry get it
* 3. when chopsticks is 1,tom can get it, else jerry get it
* 4. rice and chopsticks 's default value is 1, make tom has high priority
* 5. when tom finish the meal, he should change the rice and chopsticks 's value
* @author zero
*
*/
class UnlockedDeadLock {
private static Integer rice = 1;
private static Integer chopsticks = 1;
static class Tom extends Thread {
@Override
public void run() {
while(true) {
if(rice == 1) {
System.out.println("Tom get the rice");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(chopsticks == 1) {
System.out.println("Tom get the chopsticks and prepare to eat rice...");
rice = 2;
chopsticks = 2;
System.out.println("Tom finish the meal and give up rice and chopsticks");
break;
}else {
System.out.println("Tom find there is no chopsticks here....");
break;
}
}else {
System.out.println("Tom find there is no rice here....");
break;
}
}
}
}
static class Jerry extends Thread {
@Override
public void run() {
while(true) {
if(rice == 2) {
System.out.println("Jerry get the rice");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(chopsticks == 2) {
System.out.println("Jerry get the chopsticks and prepare to eat rice...");
System.out.println("Jerry finish the meal and give up rice and chopsticks");
break;
}else {
System.out.println("Jerry find there is no chopsticks here....Maybe Tom throw them away...");
break;
}
}else {
System.out.println("Tom has token the rice and Jerry wait...");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public static void main(String[] args) {
new Tom().start();
new Jerry().start();
}
}
运行结果:
Tom get the rice
Tom has token the rice and Jerry wait...
Tom has token the rice and Jerry wait...
Tom get the chopsticks and prepare to eat rice...
Tom finish the meal and give up rice and chopsticks
Jerry get the rice
Jerry get the chopsticks and prepare to eat rice...
Jerry finish the meal and give up rice and chopsticks
大概的说一下死锁的解决/避免思路 就不写例子了
互斥条件 线程使用的资源必须至少有一个是不能共享的 (增加米饭和筷子的数量)
至少有一个线程必须持有一个资源并且正在等待获取一个当前被其他线程持有的资源。(只有当筷子和米饭同时存在未被占用的时候才能执行吃饭的操作)
分配的资源不能从相应的线程中被强制剥夺。(Tom需要什么都可以从Jerry那里拿,只要Jerry有)
循环等待条件
第一个线程等待其他线程,后者又在等待第一个线程。(两个人都不吃了不就解决了么!!!哈哈哈)