2014-10-01 53 views
1

我有以下爲什麼Thread Interupt方法沒有打破它的睡眠方法?

package com; 
public class ThreadDemo implements Runnable { 
    @Override 
    public void run() { 
     while(true) 
     { 
      try { 
       System.out.println("Into sleep"); 
       Thread.sleep(1000000000); 
       System.out.println("Out of sleep"); 
       } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    } 
    public static void main(String args[]) { 
     ThreadDemo tD = new ThreadDemo(); 
     Thread t1 = new Thread(tD); 
     t1.start(); 
     t1.interrupt(); 
    } 
} 

我已經開始了主題這個程序,並調用它的run方法,並進入睡眠狀態的上述規定秒。

我呼籲t1.interrupt();

這是屏幕截圖

enter image description here

我的問題是,爲什麼

1.線程沒有走出睡眠狀態的?

  1. 爲什麼Into sleep被打印兩次?

回答

4

你是在一個循環:

  • 你睡覺
  • 中斷和打印堆棧跟蹤
  • 回到睡眠狀態
  • 決不被再次中斷

所以它「出來」的睡眠狀態「(否則你不會看到堆棧跟蹤) - 但是你再次調用Thread.sleep

如果你只是想睡覺一次,擺脫循環...

+0

:)我永遠也不會發現這.Thanks很多。 – Pawan 2014-10-01 15:18:27

0

鳳雲while循環中的異常是導致線程回去睡覺,所以getting rid of the loop是有道理的。另外,如果你想睡覺了較短的時間間隔,並週期性地喚醒,你可以改變你的方法:

@Override 
public void run() { 
    try { 
     while(true) 
     { 
      System.out.println("Into sleep"); 
      Thread.sleep(10000); // sleep for 10 seconds 
      System.out.println("Out of sleep"); 
     } 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
} 

那麼InterruptedException異常時,線程被中斷,將導致控制離開while循環拋出,導致線程終止。

使用中斷退出循環將是檢查的中斷標誌的線程上的另一種方式:

while (!Thread.currentThread().isInterrupted()) { 
    // ... do stuff ... 
    try { 
     Thread.sleep(5000); 
    } catch (InterruptedException e) { 
     Thread.currentThread().interrupt(); 
    } 
} 

醒目的代碼需要重新設置中斷標誌,清除異常後,這種方式當拋出異常時。

+0

爲什麼你認爲他想結束一個線程? – Logman 2014-10-01 15:37:12

+0

@Logman:這是推薦的用法(參見JCIP 7.1,第138頁:「在API或語言規範中沒有任何內容將中斷與任何特定的取消語義聯繫在一起,但實際上,對任何事物都使用中斷,但取消是脆弱和不成熟的以維持更大的應用程序。「)從OP的問題來看,他似乎預計線程會結束。 – 2014-10-01 15:43:28

+0

是的,但是當你檢查他的代碼時,很明顯他想在控制檯上看到「進入睡眠」和「離開睡眠」。問題是爲什麼有2個「入睡」而沒有「睡不着」?我假設他想看到像「進入睡眠」,「從睡夢中」,「進入睡眠」等東西,當我看到他的問題。 – Logman 2014-10-01 15:51:43

1

1.線程不是處於睡眠狀態?

他實際上只是

System.out.println("Out of sleep"); 

,因爲當你中斷線程從不執行。睡眠(10000);拋出一個異常,並

e.printStackTrace(); 

是執行,而不是

相關問題