【问题标题】:Deadlock with System.out.println and a suspended threadSystem.out.println 和挂起线程的死锁
【发布时间】:2016-08-06 11:34:48
【问题描述】:

以下代码导致我的 OSX Mavericks 出现死锁,我没有看到打印的“恢复”字符串,所以我认为这是原因。我理解suspend,resume可能会导致死锁,但没想到这么简单就搞定了。

有什么明显的原因吗?

Java 版本 java版本“1.8.0_66” Java(TM) SE 运行时环境 (build 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();
    }
}

【问题讨论】:

  • 具体是什么t

标签: java deadlock


【解决方案1】:

首先,suspendresume 已被弃用,编译器告诉你不要使用它们。期待意外。

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

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

【讨论】:

  • 感谢您格式化我的代码,使其可读。我知道不应该使用这些功能,但很好奇如果这是我所看到的,它怎么会死锁。您的进程是否以 System.out.println("resuming") 调用结束?我还将输出通过管道传输到另一个文件进行检查,但在那里看不到“恢复”字符串。我的并没有让我相信那里有某种僵局。
  • @RakeshIyer 好吧,是的,我在控制台上看到“正在恢复”。但是,suspendresume 都在平台本机线程句柄上调用函数(每个平台不同)。由于它们已被弃用,它们可能根本不做任何事情,或者产生未定义的行为,因为它们试图调用的本机函数不再工作或不存在。
【解决方案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为suspending时,可能会跑到println方法中,并锁定PrintStream实例,所以当主线程运行System.out.println("resuming");时,主线程会被阻塞。 将您的代码更改为:

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

你会正常的,希望对你有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-31
    • 1970-01-01
    • 2019-08-08
    • 2014-01-16
    • 1970-01-01
    • 2010-09-10
    相关资源
    最近更新 更多