Home > Net >  Why the deadlock doesn't work with Thread.Sleep()
Why the deadlock doesn't work with Thread.Sleep()

Time:10-14

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.

  • Related