2016-04-14 73 views
0

以下代码导致我的OSX Mavericks发生死锁,我没有看到打印的“正在恢复”字符串,因此期待这是原因。我理解暂停,恢复可能会导致僵局,但没有想到它会如此简单到达那里。System.out.println和挂起的线程造成死锁

任何明显的原因为什么?

Java版本 Java版本 “1.8.0_66” 的Java(TM)SE运行时环境(建立1.8.0_66-B17) 爪哇热点(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

什么是“t”? – markspace

回答

2

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

现在,您正在尽可能快地使用“循环”方式向控制台发送垃圾邮件,因此“正在恢复”会在屏幕上发送垃圾邮件。所以你永远不会看到它,它会离开控制台的缓冲区。

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

+0

感谢您对我的代码进行格式化,使其可读。 我明白这些函数不应该被使用,但是好奇它是如何可能发生死锁的,如果这就是我所看到的。 您的过程是否以System.out.println(“恢复”)调用结束? 我也输出到另一个文件进行检查,没有看到“恢复”字符串在那里。 我并没有让我相信那里有某种僵局。 –

+0

@RakeshIyer好的,我看到控制台上的“恢复”。但是''''suspend'''''''resume'''这两个调用平台本地线程句柄的函数(每个平台都不相同)。由于它们已被弃用,它们可能完全不做任何事情,或产生未定义的行为,因为它们尝试调用的本机函数不再工作或不存在。 –

1

我刚刚读过一本书,并知道它为什么会造成死锁。 System.out.println()方法是​​方法,这里是它的代码:

/** 
* 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 ING,它也许碰上println方法,并锁定PrintStream实例,所以当主线程运行System.out.println("resuming");,主线程将被阻塞。 昌您的代码如下:

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

你会得到它正常的,希望能帮助你。