Domanda

I have written code to illustrate a deadlock scenario in Java and I am able to achieve deadlock when synchronizing on an Object instance. However, if I change the type of the lock object to a Wrapper such as Integer, deadlock doesn't occur and the code goes to completion.

The code is below:

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();


    }

}

Can someone help explain what's going on ?

È stato utile?

Soluzione

Lock1 and Lock2 are the same objects. That's why you don't have a deadlock.

Integer a = 0;

is equivalent to

Integer a = Integer.valueOf(0);

and Integer.valueOf() caches all Integer instances between -128 and 127 (by default), as explained in the javadoc.

Use Integer lock1 = new Integer(0) and Integer lock2 = new Integer(0), and you'll get your deadlock back.

Note that using public, shared objects as locks is a very bad idea. And it's an even more bad idea to use non-final variables as locks.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top