您的位置:首页 > 编程语言 > Java开发

利用Java多线程实现死锁现象之详细解读

2015-07-29 01:11 387 查看
这个例子个人觉得非常经典,先看完,讲解在下面啦,(^__^) 嘻嘻!

/*
* 死锁:
* 同步中嵌套同步,而锁不同。
* 都在等待对方线程中的锁释放。
* */
public class Demo8 {
public static void main(String[] args) {
// 创建了一个ticket对象
Ticket2 t = new Ticket2();
// 创建了2个线程
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
// 启动线程t1
t1.start();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
t.flag = false;
// 启动线程t2
t2.start();
}
}

class Ticket2 implements Runnable {
private int tick = 100;
Object obj = new Object();
boolean flag = true;

public void run() {
if (flag) {
while (true) {
synchronized (obj) {
System.out.println("cccc");
// 调用show
show();
}
}
} else {
while (true) {
System.out.println("ddddd");
show();
}
}
}

public synchronized void show() {// 这里有两把锁 函数(this) obj
System.out.println("aaaa");
synchronized (obj) {
System.out.println("bbbb");
if (tick > 0) {
try {
Thread.sleep(10);
System.out.println(Thread.currentThread().getName()
+ "code...." + tick--);
} catch (InterruptedException e) {
e.printStackTrace();
}

}
}
}
}


结果为(各种可能,这个可能是我特意多次运行等到的结果,因为这个结果讲起来才更具代表性):并手动对其进行了一个编号

cccc                     1
aaaa                     2
bbbb                     3
ddddd                     4
Thread-0code....100                     5
cccc                     7
aaaa                     8
bbbb                     9
Thread-0code....99                     10
cccc                     11
aaaa                     12


现在对其产生的原因进行详细讲解:

首先创建了两个线程(新生态),t1先启动,flag为true,那么obj先上锁,输出cccc,然后调用show()方法,这里上了第二道锁,输出了aaaa,因为有相同的obj的锁,所以可以进入输出bbbb,为何后面是ddddd呢,因为bbbb之后休眠了10毫秒此时flag改为了false后,t2启动执行else中的代码所以才有的ddddd,休眠结束后输出Thread-0code。。。。100。对于if中始终都持有obj这把锁(预测很容易发生死锁,马上就要了,(^__^) 嘻嘻,坚持看下去),接下来的cccc是因为被t1抢到了,然后是因为t1还猛些,抢到了第二把锁synchronized,同理输出aaaa、bbbb,然后输出“Thread-0code…..99”,(关键点马上就来了,马上死锁了,最后两行代码了还剩),此时t1还是有obj这把锁,t1继续执行while循环,先遇到synchronized(obj),可以进入,因为obj当前在t2手上,输出cccc后即可就要进入show()方法了。但是不幸的是,(show()方法有synchronized关键字修饰,表示该方法有锁)被t2抢到了show这把锁,进入show()后立刻上锁,输出aaaa,可是现在t2需要obj这把锁,可是这把锁t1拿着的,所以需要等待t1释放obj这把锁,然而t1等待着show的这把锁释放呢,所以两个就在相互的等待中了,从而进入了传说中的死锁状态。

可能各位看着上面的话语太多,并且前面的“结果中的行号”并没有什么乱用,因为实在不好描述(不能用画画的方式即时演示),可是若是一点一点的看的话,将会对死锁有非常透彻的理解,希望各位看到此段话的时候,能够抱着一定要理解“死锁”的心态去阅读。有何问题在评论中留言,我会在2个工作日内回复的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: