为什么这个人为的 Java 代码会死锁?

我很难理解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!");


    }

}


拉莫斯之舞
浏览 136回答 1
1回答

POPMUISE

内部synchronized块什么都不做并不重要。Java 仍将尝试获取指定对象上的锁。无论内部synchronized块中是否没有任何处理或大量处理,您拥有的是创建死锁的最小示例:两个不同的线程,每个线程都拥有不同资源上的锁,每个线程都试图获取每个线程上的锁别人的资源。死锁发生在任一线程执行内部synchronized块之前,因为两个线程不能同时获得两个资源的锁。代码除了挂起之外什么都不做,每个线程都被阻塞了。您的呼叫interrupt太迟了,无法导致InterruptedException; 他们只在Thread. 注释掉Thread.sleep(2000)将让调用在它们仍在睡眠时interrupt捕获Threads,甚至在它们尝试获取第二个锁之前。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java