黑马程序员技术交流社区

标题: 多线程死锁,为什么只有持有静态对象引用的锁,才能死锁? [打印本页]

作者: 花伟昌    时间: 2013-3-22 09:50
标题: 多线程死锁,为什么只有持有静态对象引用的锁,才能死锁?
本帖最后由 花伟昌 于 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();

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


作者: qintoko    时间: 2013-3-22 09:59
死锁的时候两个线程等待的是一个对象,彼此等待,才会死锁。

一个对象应该怎么做?
1,单例模式
2,静态创建,直接用类去引用
作者: blackcaismine    时间: 2013-3-22 10:30
本帖最后由 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);

作者: 刘国涛    时间: 2013-3-22 10:37
因为持有静态对象引用的锁属于对象的共享数据,如果没用静态修饰的话,if和else中的synchronized中的锁就不是相同的锁,也就是说if中的z和else中的z是两个不同对象的数据,因为没用静态修饰,所以不是两个对象的共享数据,当然就不会发生死锁。
所以只有持有静态对象引用的锁,才能死锁。




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