以下代码导致我的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();
}
}
答案 0 :(得分:2)
首先,不推荐使用suspend
和resume
,编译器告诉您不要使用它们。期待意外。
现在,您通过"循环"向控制台发送垃圾邮件尽快,所以"恢复"在屏幕上发送垃圾邮件。所以你永远不会看到它,它离开了控制台的缓冲区。
如果我注释掉"循环"的打印,或者以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");
你会理解它,希望能帮到你。