黑马程序员技术交流社区

标题: 帮忙看下为什么这个死锁会有顺利运行的情况出现 [打印本页]

作者: 马富林    时间: 2013-11-19 23:43
标题: 帮忙看下为什么这个死锁会有顺利运行的情况出现
代码如下
  1. class Test implements Runnable
  2. {
  3.         private boolean flag;
  4.         Test(boolean flag)
  5.         {
  6.                 this.flag=flag;
  7.         }
  8.         public void run()
  9.         {
  10.                 if(flag)
  11.                 {
  12.                         synchronized(Mylock.lockaa)
  13.                         {
  14.                                 System.out.println("if lockaa");
  15.                                 synchronized(Mylock.lockbb)
  16.                                 {
  17.                                         System.out.println("if lockbb");
  18.                                 }
  19.                         }
  20.                 }
  21.                 else
  22.                 {
  23.                         synchronized(Mylock.lockbb)
  24.                         {
  25.                                 System.out.println("else lockbb");
  26.                                 synchronized(Mylock.lockaa)
  27.                                 {
  28.                                 System.out.println("else lockaa");
  29.                                 }
  30.                         }
  31.                 }
  32.         }
  33. }
  34. class Mylock
  35. {
  36.         static Object lockaa=new  Object();
  37.         static Object  lockbb=new Object();

  38. }
  39. class Lock
  40. {
  41.         public static void main(String[] args)
  42.         {
  43.                 Test t1=new Test(true);
  44.                 Test t2=new Test(false);
  45.                 Thread t11=new Thread(t1);
  46.                 Thread t22=new Thread(t2);
  47.                 t11.start();
  48.                 t22.start();
  49.         }
  50. }
复制代码
运行结果

08J)0ZF`2`5JT}YWV%IQ)[V.jpg (33.29 KB, 下载次数: 40)

08J)0ZF`2`5JT}YWV%IQ)[V.jpg

作者: 姚飞    时间: 2013-11-20 11:29
问题在这边: Test t1=new Test(true);
                Test t2=new Test(false);
两个线程操作了2个对象。。这里可以理解成2个锁没有联系。。你NEW了2个Test。
可以把这边弄成单例。返回引用。
作者: 姚飞    时间: 2013-11-20 11:30
死锁要操作同一个数据。。
作者: 赵许星    时间: 2013-11-20 19:51
这个毕老师已经帮咱们总结过了吧,同步的前提是:1、有两个以上线程2、使用同一个锁
锁死的机制是因为两个以上的线程获取对方资源的同时不肯放弃自身资源导致的。
                Test t1=new Test(true);
                Test t2=new Test(false);
使用了两个run,同时run中又有两个分流,相当于有2*2=4个虚拟线程在执行,楼主的程序是要让四个线程实现锁死吗?!
给你改了一下,可以死锁了,看一看是否满意。
  1. class Test implements Runnable
  2. {
  3.         private boolean flag;
  4.         Test(boolean flag)
  5.         {
  6.                 this.flag=flag;
  7.         }
  8.         public void setFlag(boolean state)
  9.         {
  10.                 this.flag = state;
  11.         }
  12.         public void run()
  13.         {
  14.                        
  15.                 if(flag)
  16.                 {
  17.                                 while(true)
  18.                                 {
  19.                                         synchronized(Mylock.lockaa)
  20.                                         {
  21.                                 System.out.println("if lockaa");
  22.                                 synchronized(Mylock.lockbb)
  23.                                 {
  24.                                         System.out.println("if lockbb");
  25.                                 }
  26.                                         }
  27.                                 }
  28.                         
  29.                 }
  30.                 else
  31.                 {
  32.                                 while(true)
  33.                                 {
  34.                                         synchronized(Mylock.lockbb)
  35.                                 {
  36.                                         System.out.println("else lockbb");
  37.                                         synchronized(Mylock.lockaa)
  38.                                         {
  39.                                         System.out.println("else lockaa");
  40.                                         }
  41.                                 }
  42.                                 }
  43.                                
  44.                 }
  45.         }
  46. }
  47. class Mylock
  48. {
  49.         static Object  lockaa=new  Object();
  50.         static Object  lockbb=new Object();

  51. }

  52. public class Lock
  53. {
  54.         public static void main(String[] args) throws InterruptedException
  55.         {
  56.                 //Test t1=new Test(true);
  57.                 Test t2=new Test(true);
  58.                 new Thread(t2).start();
  59.                
  60.                 Thread.sleep(10);               
  61.                 t2.setFlag(false);
  62.                 new Thread(t2).start();
  63.         }
  64. }
复制代码
不添加Thread.sleep(10);   的后果可能导致主线程先执行,两个线程获得执行权时flag=false执行的是同一线程体,就不会出现死锁的现象了。
作者: 马富林    时间: 2013-11-20 22:38
赵许星 发表于 2013-11-20 19:51
这个毕老师已经帮咱们总结过了吧,同步的前提是:1、有两个以上线程2、使用同一个锁
锁死的机制是因为两个 ...

可是我的程序大部分时候运行也是会出现死锁的啊。就是我运行了很多次,居然出现没有被锁死的情况。这是为什么?
作者: 马富林    时间: 2013-11-20 22:41
姚飞 发表于 2013-11-20 11:29
问题在这边: Test t1=new Test(true);
                Test t2=new Test(false);
两个线程操作了2个对象 ...

你看我发的图。4次有3次出现死锁了。证明这个程序是可以可以出现死锁的。但是有一次居然顺利运行了。没有被死锁。我是问这个。
作者: hurryup    时间: 2013-11-20 23:14
那是你rp 好,出现了小概率事件,中奖了
作者: 马富林    时间: 2013-11-20 23:56
hurryup 发表于 2013-11-20 23:14
那是你rp 好,出现了小概率事件,中奖了

嘿嘿。我就是想知道什么情况才会出现这种情况的。难道连死锁也有不靠谱的时候?
作者: 赵许星    时间: 2013-11-21 21:28
马富林 发表于 2013-11-20 23:56
嘿嘿。我就是想知道什么情况才会出现这种情况的。难道连死锁也有不靠谱的时候? ...

不是死锁不靠谱,是你写的程序有点不靠谱啊,呵呵





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