解决线程死锁问题

明日科技-w 2017-02-28 10:18:14
加精
在编写多线程程序时,必须注意资源的使用问题。如果两个线程(多个线程时情况类似)分别拥有不同的资源,而同时又需要对方释放资源才能继续运行时,就会发生死锁。本实例演示了一种解决死锁的方式,实例运行效果如图

编写类DeadLock,该类实现了Runnable接口。在run()方法中,由于去掉了一个同步块而解决了线程的死锁问题。代码如下:
package com.mingrisoft.thread;

public class DeadLock implements Runnable {
private boolean flag;// 使用flag变量作为进入不同块的标志
private static final Object o1 = new Object();
private static final Object o2 = new Object();

public void run() {
String threadName = Thread.currentThread().getName();// 获得当前线程的名字
System.out.println(threadName + ": flag = " + flag);// 输出当前线程的flag变量值
if (flag == true) {
synchronized (o1) {// 为o1加锁
try {
Thread.sleep(1000);// 线程休眠1秒钟
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(threadName + "进入同步块o1准备进入o2");// 显示进入o1块
System.out.println(threadName + "已经进入同步块o2");// 显示进入o2块
}
if (flag == false) {
synchronized (o2) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(threadName + "进入同步块o2准备进入o1");// 显示进入o2块
synchronized (o1) {
System.out.println(threadName + "已经进入同步块o1");// 显示进入o1块
}
}
}
}
}

public static void main(String[] args) {
DeadLock d1 = new DeadLock();// 创建DeadLock对象d1
DeadLock d2 = new DeadLock();// 创建DeadLock对象d2
d1.flag = true; // 将d1的flag设置为true
d2.flag = false; // 将d2的flag设置为false
new Thread(d1).start();// 在新线程中运行d1的run()方法
new Thread(d2).start();// 在新线程中运行d2的run()方法
}
}

 提示:对于4个同步块,去掉任何一个就可以解决死锁问题。
心法领悟:解决死锁的方法。
当具备以下4个条件时,就会产生死锁:资源互斥(资源只能供一个线程使用)、请求保持(拥有资源的线程在请求新的资源又不释放占有的资源)、不能剥夺(已经获得的资源在使用完成前不能剥夺)和循环等待(各个线程对资源的需求构成一个循环)。通常破坏循环等待是最有效的方法。
...全文
6259 26 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
对梦想的牵挂 2019-04-22
  • 打赏
  • 举报
回复
  • 打赏
  • 举报
回复
如果我看不懂这个 是不是说明我咋java这条路上走不下去了
zhujinqiang 2017-03-16
  • 打赏
  • 举报
回复
_明月 2017-03-14
  • 打赏
  • 举报
回复
好厉害。 学习了。。。
  • 打赏
  • 举报
回复
不错学习了。。。
qq_35027284 2017-03-10
  • 打赏
  • 举报
回复
学习学习
_long_ 2017-03-10
  • 打赏
  • 举报
回复
这样的话d1和d2并未实现同步, 那么有什么作用吗????
ydf995633068 2017-03-09
  • 打赏
  • 举报
回复
干什么不考虑线程挂起时的优化
kmlkhy 2017-03-09
  • 打赏
  • 举报
回复
学习了,说得不错
WCDJ 2017-03-08
  • 打赏
  • 举报
回复
青山一座 2017-03-06
  • 打赏
  • 举报
回复
wubaowang 2017-03-05
  • 打赏
  • 举报
回复
不错学习了。。。
dragonlw 2017-03-04
  • 打赏
  • 举报
回复
In this way, the two threads are in dead lock status. A occupies R1 and require resource R2, while B occupies R2 and require resource R1. None of them is willing to release occupied resource and then two of them are dead finally. public class DeadLock implements Runnable { private boolean flag;// 使用flag变量作为进入不同块的标志 private static final Object o1 = new Object(); private static final Object o2 = new Object(); public void run() { String threadName = Thread.currentThread().getName();// 获得当前线程的名字 System.out.println(threadName + ": flag = " + flag);// 输出当前线程的flag变量值 if (flag == true) { synchronized (o1) {// 为o1加锁 try { Thread.sleep(1000);// 线程休眠1秒钟 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(threadName + "进入同步块o1准备进入o2");// 显示进入o1块 synchronized (o2) { System.out.println(threadName + "已经进入同步块o2");// 显示进入o2块 } } } if (flag == false) { synchronized (o2) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(threadName + "进入同步块o2准备进入o1");// 显示进入o2块 synchronized (o1) { System.out.println(threadName + "已经进入同步块o1");// 显示进入o1块 } } } } public static void main(String[] args) { DeadLock d1 = new DeadLock();// 创建DeadLock对象d1 DeadLock d2 = new DeadLock();// 创建DeadLock对象d2 d1.flag = true; // 将d1的flag设置为true d2.flag = false; // 将d2的flag设置为false new Thread(d1).start();// 在新线程中运行d1的run()方法 new Thread(d2).start();// 在新线程中运行d2的run()方法 } }
longde300 2017-03-04
  • 打赏
  • 举报
回复
好东西 收下了
小灰狼 2017-03-03
  • 打赏
  • 举报
回复
楼主你的程序当然不会死锁啦 第二个线程 d2.flag = false 启动时判断 flag == false,直接退出线程,根本没有机会和 d1 竞争资源 就算是括号放错了位置,d1、d2 竞争的是不同的资源,也没有机会产生死锁。 如果把资源比作会议室,线程比作开会的部门。只有两个部门都竞争同一个会议室时,才会有冲突,如果会议室足够多,规定研发部用一楼会议室、市场部用二楼会议室,则他们就不存在冲突。
aierda 2017-03-03
  • 打赏
  • 举报
回复
学习了,说得不错
Jerry_Huang_94 2017-03-03
  • 打赏
  • 举报
回复
liuhuanleijava 2017-03-01
  • 打赏
  • 举报
回复
eziowayne 2017-03-01
  • 打赏
  • 举报
回复
jiajing1990_ 2017-03-01
  • 打赏
  • 举报
回复
加载更多回复(6)

67,550

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧