Я делаю некоторые упражнения с Java (некоторые из вас могут предположить, откуда взялся код). Я пытаюсь спровоцировать тупиковую ситуацию с помощью следующего кода:
class Resource {
public Integer value = 42;
}
public class DeadLockRisk implements Runnable {
private Resource resourceA = new Resource();
private Resource resourceB = new Resource();
public void write(int a, int b) {
System.out.println(Thread.currentThread().getName() + " try write Lock A");
synchronized(resourceA) {
System.out.println(Thread.currentThread().getName() + " write Lock A");
System.out.println(Thread.currentThread().getName() + " try write Lock B");
synchronized(resourceB) {
System.out.println(Thread.currentThread().getName() + " write Lock B");
resourceA.value = a;
resourceB.value = b;
//sit on it!
//try { Thread.sleep(5000); } catch (Exception e) {}
System.out.println(Thread.currentThread().getName() + " release write B");
}
System.out.println(Thread.currentThread().getName() + " release write A");
}
}
public int read() {
Integer retVal;
System.out.println(Thread.currentThread().getName() + " try read Lock B");
synchronized(resourceB) {
System.out.println(Thread.currentThread().getName() + " read Lock B");
System.out.println(Thread.currentThread().getName() + " try read Lock A");
synchronized(resourceA) {
System.out.println(Thread.currentThread().getName() + " read Lock A");
retVal = resourceB.value + resourceA.value;
System.out.println(Thread.currentThread().getName() + " release read A");
}
System.out.println(Thread.currentThread().getName() + " release read B");
}
return retVal;
}
public void run() {
if (Thread.currentThread().getName().equals("Thread-1")) {
write(1,2);
}
System.out.println(read());
}
public static void main(String[] args) {
Thread ta = new Thread(new DeadLockRisk());
Thread tb = new Thread(new DeadLockRisk());
ta.start(); tb.start();
}
}
(javac-версия javac 1.6.0_0
uname -a Linux inspiron 2.6.29 # 1 SMP Sat 16 мая 10:56:17 CEST 2009 i686 GNU / Linux)
и получите (среди прочих ситуаций) вывод ниже:
Thread-1 try write Lock A
Thread-0 try read Lock B
Thread-1 write Lock A <=====
Thread-0 read Lock B
Thread-1 try write Lock B
Thread-0 try read Lock A
Thread-1 write Lock B
Thread-0 read Lock A <=====
Thread-1 release write B
Thread-0 release read A
Thread-1 release write A
Thread-0 release read B
Thread-1 try read Lock B
154
Thread-1 read Lock B
Thread-1 try read Lock A
Thread-1 read Lock A
Thread-1 release read A
Thread-1 release read B
3
Что я вижу не так?
Как Thread-0 может даже войти в критическую секцию в read () и получить блокировку на A, прежде чем блокировка будет снята Thread-1. Это возможно, потому что вывод не является синхронным?
С этим кодом тупик не возникает.