A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 花伟昌 于 2013-3-22 20:26 编辑

class Z
{
       public void say()
       {
          System.out.println("你把书给我,我把画给你");
       }
       public void get()
      {
          System.out.println("Z得到书了");
      }
}
class L
{
       public void say()
      {
          System.out.println("你把画给我,我把书给你");
      }
       public void get()
      {
          System.out.println("L得到画了");
       }
}
class DeadLock implements Runnable
{
      static Z z=new Z();//为什么只有持有静态对象引用的锁,才能死锁
      static L l=new L();//为什么只有持有静态对象引用的锁,才能死锁
      boolean flag;
      public void run()
     {
          while(true)
           {
   
                if (flag)
                 {
                        synchronized(z)
                        {
                             z.say();
             
         try{Thread.sleep(10);}catch(InterruptedException e){}    
         
                         synchronized(l)
                        {
                             z.get();
                        }
                        }
                  }
   
                     else
                  {
                         synchronized(l)
                        {
   
                           l.say();
        try{Thread.sleep(10);}catch(InterruptedException e){}
                         synchronized(z)
                        {
                             l.get();
                         }
                         }
                   }
             }
      }

}

class ThreadDeadLock
{
        public static void main(String[] args)
       {
  DeadLock d=new DeadLock();
  DeadLock d1=new DeadLock();
  d.flag=true;
  d1.flag=false;
     
  Thread t1=new Thread(d);
  Thread t2=new Thread(d1);
  t1.start();
  t2.start();

  
        }
}
上面是个多线程死锁程序,为什么只有持有静态对象引用的锁,才能死锁?

点评

如果问题未解决,请继续追问回复者,如果问题已经解决,请将分类改为“已解决”,谢谢  发表于 2013-3-22 12:35

评分

参与人数 1技术分 +1 收起 理由
洪建超 + 1

查看全部评分

3 个回复

倒序浏览
死锁的时候两个线程等待的是一个对象,彼此等待,才会死锁。

一个对象应该怎么做?
1,单例模式
2,静态创建,直接用类去引用
回复 使用道具 举报
本帖最后由 blackcaismine 于 2013-3-22 10:35 编辑

因为静态的话,z和L的对象是唯一的,如果你不加静态,那么当你
  DeadLock d=new DeadLock();
  DeadLock d1=new DeadLock();
的时候,new出来的是俩组z与L的对象,那么就有两组z与L的锁,就不会产生死锁了

如果你在DeadLock里面加上一个构造函数
class DeadLock implements Runnable
{
      boolean flag;
      Z z=null;
      L l=null;
      DeadLock(Z z,L l)
      {
          this.z = z;
          this.l = l;
      }
      public void run()
     {
.....
然后在主函数里new z与L 传递进去,就会产生死锁了。
Z z=new Z();
L l=new L();
DeadLock d=new DeadLock(z,l);
DeadLock d1=new DeadLock(z,l);

评分

参与人数 1技术分 +1 收起 理由
黄玉昆 + 1

查看全部评分

回复 使用道具 举报
因为持有静态对象引用的锁属于对象的共享数据,如果没用静态修饰的话,if和else中的synchronized中的锁就不是相同的锁,也就是说if中的z和else中的z是两个不同对象的数据,因为没用静态修饰,所以不是两个对象的共享数据,当然就不会发生死锁。
所以只有持有静态对象引用的锁,才能死锁。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马