在编写多线程程序时,必须注意资源的使用问题。如果两个线程(多个线程时情况类似)分别拥有不同的资源,而同时又需要对方释放资源才能继续运行时,就会发生死锁。本实例演示了一种解决死锁的方式,实例运行效果如图
编写类DeadLock,该类实现了Runnable接口。在run()方法中,由于去掉了一个同步块而解决了线程的死锁问题。代码如下:
提示:对于4个同步块,去掉任何一个就可以解决死锁问题。
心法领悟:解决死锁的方法。
当具备以下4个条件时,就会产生死锁:资源互斥(资源只能供一个线程使用)、请求保持(拥有资源的线程在请求新的资源又不释放占有的资源)、不能剥夺(已经获得的资源在使用完成前不能剥夺)和循环等待(各个线程对资源的需求构成一个循环)。通常破坏循环等待是最有效的方法。
![](http://img.bbs.csdn.net/upload/201702/28/1488248160_386080.png)
编写类DeadLock,该类实现了Runnable接口。在run()方法中,由于去掉了一个同步块而解决了线程的死锁问题。代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
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个条件时,就会产生死锁:资源互斥(资源只能供一个线程使用)、请求保持(拥有资源的线程在请求新的资源又不释放占有的资源)、不能剥夺(已经获得的资源在使用完成前不能剥夺)和循环等待(各个线程对资源的需求构成一个循环)。通常破坏循环等待是最有效的方法。