黑马程序员技术交流社区

标题: 死锁问题 [打印本页]

作者: volvoxc    时间: 2014-2-25 12:21
标题: 死锁问题
这段小程序,我不明白为什么三个线程都能拿到obj1的锁,而都又拿不到obj2的锁,快速的黑马同学们,谁能给解释一下啊
  1. public class Test {

  2.     public static void main(String[] args) throws InterruptedException {
  3.         Object obj1 = new Object();
  4.         Object obj2 = new Object();
  5.         Object obj3 = new Object();

  6.         Thread t1 = new Thread(new SyncThread(obj1, obj2), "t1");
  7.         Thread t2 = new Thread(new SyncThread(obj2, obj3), "t2");
  8.         Thread t3 = new Thread(new SyncThread(obj3, obj1), "t3");

  9.         t1.start();
  10.         Thread.sleep(1000);
  11.         t2.start();
  12.         Thread.sleep(1000);
  13.         t3.start();

  14.     }

  15. }

  16. class SyncThread implements Runnable{
  17.     private Object obj1;
  18.     private Object obj2;

  19.     public SyncThread(Object o1, Object o2){
  20.         this.obj1=o1;
  21.         this.obj2=o2;
  22.     }
  23.     @Override
  24.     public void run() {
  25.         String name = Thread.currentThread().getName();
  26.         synchronized (obj1) {
  27.          System.out.println(name + "进入obj1 ");
  28.          work();
  29.                  System.out.println(name + "苏醒过来了 ");
  30.          synchronized (obj2) {
  31.             System.out.println(name + " 进入obj2 ");
  32.             work();
  33.         }
  34.          System.out.println(name + " 出obj2 ");
  35.         }
  36.         System.out.println(name + " 出obj1 ");
  37.         System.out.println(name + " 结束");
  38.     }
  39.     private void work() {
  40.         try {
  41.             Thread.sleep(3000);
  42.         } catch (InterruptedException e) {
  43.             e.printStackTrace();
  44.         }
  45.     }
  46. }
复制代码




作者: volvoxc    时间: 2014-2-25 12:24
我的运行结果是
t1进入obj1
t2进入obj1
t3进入obj1
t1苏醒过来了
t2苏醒过来了
t3苏醒过来了
然后程序就一直等待了。。。
作者: 薛旻    时间: 2014-2-25 13:47
你这个明显互相占着资源,死锁了啊。
t1拿到obj1然后等待一会,这时候t2拿到obj2等待,t3拿到obj3等待
然后t1苏醒要拿obj2结果锁被t2拿了,阻塞了
      t2苏醒要拿obj3结果锁被t3拿了,阻塞了
      t3苏醒要拿obj1结果锁被t1拿了,阻塞了
所以三个线程全挂了。
你至少要让一个如果阻塞的话,释放自己拿到的锁。
作者: volvoxc    时间: 2014-2-25 14:00
薛旻 发表于 2014-2-25 13:47
你这个明显互相占着资源,死锁了啊。
t1拿到obj1然后等待一会,这时候t2拿到obj2等待,t3拿到obj3等待
然后 ...

t1,t2,t3拿的是同一个锁吗
作者: 薛旻    时间: 2014-2-25 14:06
Thread t1 = new Thread(new SyncThread(obj1, obj2), "t1");
Thread t2 = new Thread(new SyncThread(obj2, obj3), "t2");
Thread t3 = new Thread(new SyncThread(obj3, obj1), "t3");
你写的代码里传入的三个对象obj1,obj2,obj3就是三个锁,t1,t2,t3操作就是这三个锁

作者: volvoxc    时间: 2014-2-25 14:12
薛旻 发表于 2014-2-25 14:06
Thread t1 = new Thread(new SyncThread(obj1, obj2), "t1");
Thread t2 = new Thread(new SyncThread(obj2 ...

明白了。3ku
作者: 薛旻    时间: 2014-2-25 14:18
本帖最后由 薛旻 于 2014-2-25 14:19 编辑
volvoxc 发表于 2014-2-25 14:12
明白了。3ku

我说的锁就是在
synchronized(锁){

}你传入了obj1,obj2,obj3
JDK1.5 有一个接口Lock 和 Condition 替代了synchronized 和 Object的阻塞唤醒方法,常识新的特性吧,前提是弄懂synchronized同步

作者: 平凡成就非凡    时间: 2014-2-25 14:33
你这个程序死锁吗?你的run()方法中要有
if(flag==true)
{
  synchronized(obj1)   
{     synchronized(obj2)
      {         }  
}               
}
else(flag==false)
{
  synchronized(obj2)   
{     synchronized(obj1)
      {         }  
}               
}
让两个线程,一个执行if(),另一个执行else(),它们个自执行都要彼此的锁,就会死锁啦




作者: xiaochen33520    时间: 2014-2-25 16:38
很简单,3个线程(A,B,C),A拿了obj1锁,一B拿到了obj2锁。A要用到obj2锁,B不放,B要用到obj1锁,A不放,就会导致死锁。
作者: jkenny    时间: 2014-2-25 20:25
主线程--t1(线程)开始---锁obj1---打印(t1进入obj1)
t1线程“睡眠3秒”
-----------------------------------------
主线程--t2(线程)开始---锁obj2---打印(t2进入obj1)
t2线程“睡眠3秒”[t1线程还有2秒醒]
-----------------------------------------
主线程--t3(线程)开始---锁obj3---打印(t3进入obj1)
t3线程“睡眠3秒”[t1线程还有1秒醒][t2线程还有2秒醒]
-----------------------------------------
[t1线程醒了][t2线程还有1秒醒][t3线程还有2秒醒]
t1(线程)打印(t1苏醒过来了),此时要进入obj2锁的代码块,但obj2还锁着
-----------------------------------------
[t2线程醒了][t3线程还有1秒醒]
t2(线程)打印(t2苏醒过来了),此时要进入obj2锁的代码块,但obj2还锁着
-----------------------------------------
[t3线程醒了]
t3(线程)打印(t3苏醒过来了),此时要进入obj2锁的代码块,但obj2还锁着
-----------------------------------------

obj2一直锁着锁着,所以都进不了。
如果将Thread.sleep(3000);改成小一点的数值就可以了。如Thread.sleep(10);




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2