2016-04-14 103 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"); 

你會得到它正常的,希望能幫助你。