为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

拉莫斯之舞 2021-08-04 10:23:53
我很难理解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 回答

?
POPMUISE

TA贡献1765条经验 获得超5个赞

内部synchronized块什么都不做并不重要。Java 仍将尝试获取指定对象上的锁。

无论内部synchronized块中是否没有任何处理或大量处理,您拥有的是创建死锁的最小示例:两个不同的线程,每个线程都拥有不同资源上的锁,每个线程都试图获取每个线程上的锁别人的资源。

死锁发生在任一线程执行内部synchronized块之前,因为两个线程不能同时获得两个资源的锁。

代码除了挂起之外什么都不做,每个线程都被阻塞了。您的呼叫interrupt太迟了,无法导致InterruptedException; 他们只在Thread. 注释掉Thread.sleep(2000)将让调用在它们仍在睡眠时interrupt捕获Threads,甚至在它们尝试获取第二个锁之前。


查看完整回答
反对 回复 2021-08-04
  • 1 回答
  • 0 关注
  • 135 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信