我编写了代码来说明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();
}
}
有人可以帮助解释发生了什么吗?
答案 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)
,您就会遇到僵局。
请注意,将公共共享对象用作锁是一个非常糟糕的主意。将非最终变量用作锁定是一个更糟糕的主意。