为什么这会造成Java代码死锁?

时间:2018-08-20 22:21:29

标签: java multithreading concurrency locking deadlock

我很难理解synchronized。由于第一个线程对对象2不做任何事情,难道它不会在一秒钟内“解锁”所有东西吗?

public class Uninterruptible {
    public static void main(String[] args) throws InterruptedException {
        final Object o1 = new Object(); final Object o2 = new Object();

        Thread t1 = new Thread() {
            public void run() {
                try {
                    synchronized(o1) {
                        Thread.sleep(1000);
                        synchronized(o2) {}
                    }
                } catch(InterruptedException e) { System.out.println("t1 interrupted"); }
            }
        };

        Thread t2 = new Thread() {
            public void run() {
                try {
                    synchronized(o2) {
                        Thread.sleep(1000);
                        synchronized(o1) {}
                    }
                } catch(InterruptedException e) { System.out.println("t2 interrupted"); }
            }
        };

        t1.start(); t2.start();
        Thread.sleep(2000);
        t1.interrupt(); t2.interrupt();
        t1.join(); t2.join();

        System.out.println("Donezo!");

    }
}

1 个答案:

答案 0 :(得分:3)

内部synchronized块什么都没做。 Java仍将尝试获取对指定对象的锁定。

无论内部synchronized块中什么都没有,也没有大量处理,创建死锁的最小示例就是:两个不同的线程,每个线程拥有对不同资源的锁,每个尝试获取对方资源锁定的人。

死锁发生在任何一个线程甚至没有执行内部synchronized块之前,因为两个线程都无法同时获得这两个资源的锁。

在结束代码时,除了挂起之外,什么也没做,每个线程都被阻塞了。您对interrupt的呼叫为时已晚,无法引起InterruptedException;他们仅在Thread中设置“中断状态”。注释掉Thread.sleep(2000)可以使到interrupt的呼叫在它们Thread仍处于休眠状态时捕获,甚至没有试图获得第二个锁。