锁定Wrapper类实例与对象

时间:2014-05-06 17:23:20

标签: java concurrency

我编写了代码来说明Java中的死锁情况,并且我可以在对象实例上进行同步时实现死锁。但是,如果我将锁定对象的类型更改为诸如Integer之类的包装器,则不会发生死锁并且代码将完成。

代码如下:

package my.local.concurrency;

public class DeadlockDemo {

**// Using Integer will not result in deadlock, but Object does.**
//   public static Integer Lock1 = 0;
       //public static Integer Lock2 = 0;

       public static Object Lock1 = new Object();
       public static Object Lock2 = new Object();

       private class Runnable1 implements Runnable
       {
           public void run()
           {
               synchronized(Lock1)
               {
                   System.out.println("Thread 1: Holding lock 1...");
                   try { Thread.sleep(10); }
                    catch (InterruptedException e) {}
                    System.out.println("Thread 1: Waiting for lock 2...");
                    synchronized (Lock2) {
                       System.out.println("Thread 1: Holding lock 1 & 2...");
                    }
               }
           }
       }

       private class Runnable2 implements Runnable
       {
           public void run()
           {
               synchronized(Lock2)
               {
                   System.out.println("Thread 2: Holding lock 2...");
                   try { Thread.sleep(10); }
                    catch (InterruptedException e) {}
                    System.out.println("Thread 2: Waiting for lock 1...");
                    synchronized (Lock1) {
                       System.out.println("Thread 2: Holding lock 1 & 2...");
                    }
               }
           }
       }

    public static void main(String[] args) {
        Runnable1 r1=new DeadlockDemo().new Runnable1();

        new Thread(r1).start();

            Runnable2 r2=new DeadlockDemo().new Runnable2();

        new Thread(r2).start();


    }

}

有人可以帮助解释发生了什么吗?

1 个答案:

答案 0 :(得分:4)

Lock1和Lock2是相同的对象。这就是为什么你没有陷入僵局。

Integer a = 0;

相当于

Integer a = Integer.valueOf(0);

Integer.valueOf()将所有Integer实例缓存在-128和127之间(默认情况下),如the javadoc中所述。

使用Integer lock1 = new Integer(0)Integer lock2 = new Integer(0),您就会遇到僵局。

请注意,将公共共享对象用作锁是一个非常糟糕的主意。将非最终变量用作锁定是一个更糟糕的主意。