一个简单的死锁例子
在实际编程中,要尽量避免出现死锁的情况,但是让你故意写一个死锁的程序时似乎也不太简单(有公司会出这样的面试题),以下是一个简单的死锁例子。
线程的同步化可能会造成死锁,死锁发生在两个线程相互持有对方正在等待的东西(实际是两个线程共享的东西)。只要有两个线程和两个对象就可能产生死锁。
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
46
47
48
49
50
51
52
53
54
|
/**
* 一个简单的死锁类
* 当DeadLock类的对象flag==1时(td1),先锁定o1,睡眠500毫秒
* 而td1在睡眠的时候另一个flag==0的对象(td2)线程启动,先锁定o2,睡眠500毫秒
* td1睡眠结束后需要锁定o2才能继续执行,而此时o2已被td2锁定;
* td2睡眠结束后需要锁定o1才能继续执行,而此时o1已被td1锁定;
* td1、td2相互等待,都需要得到对方锁定的资源才能继续执行,从而死锁。
*/
public
class
DeadLock
implements
Runnable {
public
int
flag =
1
;
//静态对象是类的所有对象共享的
private
static
Object o1 =
new
Object(), o2 =
new
Object();
@Override
public
void
run() {
System.out.println(
"flag="
+ flag);
if
(flag ==
1
) {
synchronized
(o1) {
try
{
Thread.sleep(
500
);
}
catch
(Exception e) {
e.printStackTrace();
}
synchronized
(o2) {
System.out.println(
"1"
);
}
}
}
if
(flag ==
0
) {
synchronized
(o2) {
try
{
Thread.sleep(
500
);
}
catch
(Exception e) {
e.printStackTrace();
}
synchronized
(o1) {
System.out.println(
"0"
);
}
}
}
}
public
static
void
main(String[] args) {
DeadLock td1 =
new
DeadLock();
DeadLock td2 =
new
DeadLock();
td1.flag =
1
;
td2.flag =
0
;
//td1,td2都处于可执行状态,但JVM线程调度先执行哪个线程是不确定的。
//td2的run()可能在td1的run()之前运行
new
Thread(td1).start();
new
Thread(td2).start();
}
}
|