The code use Java 8:
public class MustDeadLock {
private static final Object obj1 = new Object();
private static final Object obj2 = new Object();
public static void main(String[] args) {
mockDeadLock();
}
public static void mockDeadLock() {
CompletableFuture cf1 = CompletableFuture.runAsync(() -> {
synchronized (obj1) {
System.out.println("thread A got lock: obj1");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("thread A ready to get the rest lock");
synchronized (obj2) {
System.out.println("thread A got all locks");
}
}
});
CompletableFuture cf2 = CompletableFuture.runAsync(() -> {
synchronized (obj2) {
System.out.println("thread B got lock: obj2");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("thread B ready to get the rest lock");
synchronized (obj1) {
System.out.println("thread B got all locks");
}
}
});
CompletableFuture.allOf(cf1, cf2);
System.out.println("program ready to terminate");
}
}
I'm wondering why
System.out.println("thread A ready to get the rest lock");
and
System.out.println("thread B ready to get the rest lock");)
don't get executed.
Why does it just print:
thread B got lock: obj2
thread A got lock: obj1
program ready to terminate
and then terminate the program rather than blocking?
CodePudding user response:
Simply because your main thread continues the execution while the other threads are sleeping.
If you want to wait for these threads to complete before continuing the execution, you can for example join them before the end of the method:
// rest of the program
cf1.join();
cf2.join();
System.out.println("program ready to terminate");
This will print:
thread B got lock: obj2
thread A got lock: obj1
thread B ready to get the rest lock
thread A ready to get the rest lock
This will produce the deadlock and the program will never terminate.