class Lock implements Runnable{
public int i = 1;
static Object l1 = new Object();
static Object l2 = new Object();

           public void run() {
System.out.println("死锁开始");
  if(i ==1) {
    synchronized(l1) {
      try {
        Thread.sleep(500);
      }catch(InterruptedException e) {
           System.out.println("睡眠被打断");
           e.printStackTrace();        
      } 
    
    synchronized(l2) {
      System.out.println("需要两个对象开锁");
      }
    } 
  }
  if(i == 0) {
    synchronized(l2) {
      try {
        Thread.sleep(500);
      }catch(InterruptedException e) {
           System.out.println("睡眠被打断");
           e.printStackTrace();        
       } 
   
    synchronized(l1) {
      System.out.println("需要两个对象开锁");
    } 
    }
  }
}
}


public class TestLock {

public static void main(String args[]){
Lock t1 = new Lock();
Lock t2 = new Lock();
t1.i = 1;
t2.i = 0;
Thread th1 = new Thread(t1);
Thread th2 = new Thread(t2);
th1.start();
th2.start();
}
}这是一个死锁的代码,问题疑问在于顶端两个Obj对象,如果加了static 就会死锁。如果去掉static 就不会死锁。这个原因是什么呢?

解决方案 »

  1.   

    static是静态的,所有的对象都共享的,所以虽然你new了两个对象出来,这两个对象还是同一个,所以会死锁,如果不static,则说明每个对象都有自己的monitor对象
      

  2.   

    Lock t1 = new Lock();如果不是static, 则每个线程之间各自使用各自的锁,不会出现死锁了(顺序执行)
      

  3.   

    static Object l1 = new Object();
    static Object l2 = new Object();
    这两个栈对象指向同一块内存,他们的equals()是相等的
      

  4.   

    7楼大哥,不会指向同一块内存吧?我是JAVA初学者,我都有点儿晕了。是不是指向同一块内存???
      

  5.   

    来拿分的.上面的都说得很清楚了.
    static是类变量.不属于任何对象.
      

  6.   

    STATIC是静态的,不会因为实例而改变。
      

  7.   

    类中静态变量只是在第一次调用该类时初始化,
    所以这里 t1 中的对象 l1 ,l2 和 t2 中的 l1 ,l2 是一样的
      

  8.   

    7楼的说错了,只要有new,就会重新开辟内存空间,l1和l2肯定不一样!!!public class TestStaticDemo01
    {
    static Object t1=new Object();
    static Object t2=new Object();
    public static void main(String[] args)
    {
    System.out.println(t1.equals(t2));
    }
    }很明显地输出FALSE
      

  9.   

    其实类上的说的有点不足:
    你可以把题目简单化:去掉与static Object l2 = new Object();有关的代码。
    测试发现如下:
    System.out.println(t1.l1.equals(t2.l1));
    你会发现true,说明两个对象的内部成员变量都一样。当然是因为static。所以在线程启动后,这样执行的。
    t1线程启动,t2线程启动,但是t1线程用到l1对象叫他去睡觉,t2线程也用到了l1对象叫他开工。这样l1对象就不知道干什么了。所以死锁。同理l2对象也是。这次你觉得满意吗。那就给分吧。谢谢。
      

  10.   

    这个问题和l1,l2没有关系,而是t1中的l1和t2中的l1关系,或者t1中的l2和t2中的l2之间的关系。
    我们要看清到底是谁跟谁的关系。不能拿人和猪比较美。当然15类的说new的对象会开辟空间,还真是谢谢您这么说,不然我还不知道怎么下手。最近一直致力于C#,java都陌生了。