代码之家  ›  专栏  ›  技术社区  ›  dsp_099

为什么这个设计的Java代码死锁?

  •  -1
  • dsp_099  · 技术社区  · 7 年前

    我很难理解 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 回复  |  直到 7 年前
        1
  •  3
  •   rgettman    7 年前

    无论内心 synchronized 积木不起作用。Java仍将尝试获取指定对象上的锁。

    无论你内心是一无所有还是大量的处理 同步的 块,您所拥有的是创建死锁的最小示例:两个不同的线程,每个线程在不同的资源上拥有锁,每个线程都试图获取彼此资源上的锁。

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

    代码最终只会挂起,每个线程都被阻塞。你的电话 interrupt 太晚了,不能导致 InterruptedException ;它们只在 Thread . 述评 Thread.sleep(2000) 会让电话转到 打断 抓住 螺纹 当他们还在睡觉时,甚至在他们试图获得第二把锁之前。