实践中的Java并发:清单8.3。诱导锁排序以防止死锁
我无法理解为什么书中清单8.3中提到的代码不容易死锁。当我运行代码时,它不会导致死锁。我从书中吸取了这个想法,修改了代码。 节目如下:-实践中的Java并发:清单8.3。诱导锁排序以防止死锁,java,multithreading,Java,Multithreading,我无法理解为什么书中清单8.3中提到的代码不容易死锁。当我运行代码时,它不会导致死锁。我从书中吸取了这个想法,修改了代码。 节目如下:- public class LockOrderingDeadLockSolved { private final Object left = new Object(); private final Object right = new Object(); private final Object tieLock = new Obj
public class LockOrderingDeadLockSolved {
private final Object left = new Object();
private final Object right = new Object();
private final Object tieLock = new Object();
public static void main(String[] args) {
LockOrderingDeadLockSolved obj = new LockOrderingDeadLockSolved();
int leftHash = System.identityHashCode(obj.left);
int rightHash = System.identityHashCode(obj.right);
System.out.println(leftHash +" --- " + rightHash);
Thread t = new Thread() {
public void run() {
if (leftHash < rightHash)
obj.leftRight();
else if (leftHash > rightHash)
obj.rightLeft();
else
obj.tieLockMethod();
}
};
Thread t1 = new Thread() {
public void run() {
if (leftHash < rightHash)
obj.leftRight();
else if (leftHash > rightHash)
obj.rightLeft();
else
obj.tieLockMethod();
}
};
t.start();
t1.start();
}
private void leftRight() {
synchronized (left) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (right) {
System.out.println("Left right -- left right lock");
}
}
}
private void rightLeft() {
synchronized (right) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (left) {
System.out.println("Right left -- right left lock");
}
}
}
private void tieLockMethod() {
synchronized (tieLock) {
synchronized (left) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (right) {
System.out.println("Right left --- tie lock");
}
}
}
}
}
}如果以相同的顺序获取锁,则不会发生死锁 要使示例死锁,必须以不同的顺序重复获取相同的锁。这可以通过以下代码完成
private static final Object left = new Object();
private static final Object right = new Object();
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
while (true) {
synchronized (left) {
synchronized (right) {
System.out.println("Left right -- left right lock");
}
}
}
});
Thread t2 = new Thread(() -> {
while (true) {
synchronized (right) {
synchronized (left) {
System.out.println("Right left -- right left lock");
}
}
}
});
t1.start();
t2.start();
}
如果锁以相同的顺序获取,则不会发生死锁 要使示例死锁,必须以不同的顺序重复获取相同的锁。这可以通过以下代码完成
private static final Object left = new Object();
private static final Object right = new Object();
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
while (true) {
synchronized (left) {
synchronized (right) {
System.out.println("Left right -- left right lock");
}
}
}
});
Thread t2 = new Thread(() -> {
while (true) {
synchronized (right) {
synchronized (left) {
System.out.println("Right left -- right left lock");
}
}
}
});
t1.start();
t2.start();
}
为什么会出现僵局?一个线程将首先得到
左
,然后当它完成时,另一个线程将去。但是,如果我删除检查哈希代码比较的条件,它将导致死锁。易于死锁的程序与不易于死锁的程序做的事情完全不同,因此一个死锁,另一个不死锁。您不能将运行相同方法的两个线程与运行不同方法的两个线程进行比较,并期望它们以相同的方式运行。谢谢。现在我明白了,为什么会出现僵局?一个线程将首先得到左
,然后当它完成时,另一个线程将去。但是,如果我删除检查哈希代码比较的条件,它将导致死锁。易于死锁的程序与不易于死锁的程序做的事情完全不同,因此一个死锁,另一个不死锁。您不能将运行相同方法的两个线程与运行不同方法的两个线程进行比较,并期望它们以相同的方式运行。谢谢。现在我明白了。