与System.out.println和挂起的线程死锁

时间:2016-04-14 18:28:05

标签: java deadlock

以下代码导致我的OSX Mavericks出现死锁,我没有看到打印出“恢复”字符串,所以期待这就是原因。我理解暂停,恢复可能会导致死锁,但是没想到它会如此简单到达那里。

任何明显的原因?

Java版本 java版“1.8.0_66” Java(TM)SE运行时环境(版本1.8.0_66-b17) Java HotSpot(TM)64位服务器VM(版本25.66-b17,混合模式)

class TestThread {
    public static void main(String args[]) throws InterruptedException {
        Thread t = new Thread() {
            public void run() { 
                while (!isInterrupted()) { 
                    System.out.println("looping");
                }
            }
        };

        t.start();
        Thread.sleep(1000);
        t.suspend();
        Thread.sleep(5000);
        System.out.println("resuming");
        t.resume();
        Thread.sleep(2000);
        t.interrupt();
    }
}

2 个答案:

答案 0 :(得分:2)

首先,不推荐使用suspendresume,编译器告诉您不要使用它们。期待意外。

现在,您通过"循环"向控制台发送垃圾邮件尽快,所以"恢复"在屏幕上发送垃圾邮件。所以你永远不会看到它,它离开了控制台的缓冲区。

如果我注释掉"循环"的打印,或者以500毫秒的间隔打印,我可以看到"恢复"很好。

答案 1 :(得分:2)

我刚读了一本书,并知道它为什么会出现死锁。System.out.println()方法是一个synchronized方法,这是它的代码:

/**
 * Prints a String and then terminate the line.  This method behaves as
 * though it invokes <code>{@link #print(String)}</code> and then
 * <code>{@link #println()}</code>.
 *
 * @param x  The <code>String</code> to be printed.
 */
public void println(String x) {
    synchronized (this) {
        print(x);
        newLine();
    }
}

所以当线程t为suspend时,它可能会运行到println方法,并锁定PrintStream实例,所以当主线程运行System.out.println("resuming");时,主线程将被阻止。 把你的代码改为:

    //System.out.println("resuming");
    t.resume();
    Thread.sleep(2000);
    t.interrupt();
    System.out.println("end");

你会理解它,希望能帮到你。