2015-08-08 49 views
3

我正在嘗試學習線程中斷以及如何在不調用stop的情況下使線程終止。如何用線程中斷方法停止線程

public class Test implements Runnable{ 
     static Thread threadTest=null; 
     public static void main(String args[]){ 
      System.out.println("Hello i am main thread"); 
      Test thread= new Test(); 
      threadTest= new Thread(thread); 
      threadTest.start(); 
} 

private static void exitThread() { 
    threadTest.interrupt(); 
} 

@Override 
public void run() { 
    boolean run = true; 
    while (run) { 
     try { 
      System.out.println("Sleeping"); 
      Thread.sleep((long) 10000); 
      exitThread(); 
      System.out.println("Processing"); 

     } catch (InterruptedException e) { 

      run = false; 
     } 
    } 

} 


} 

輸出

Hello i am main thread 

Sleeping 

Processing 

Sleeping 

我無法理解爲什麼睡覺打印第二次打斷異常被拋出,而不是第一再寄一次檢查了下volatile關鍵字用來帖子第二次停止java.but中的線程,但我無法理解在這種情況下如何使用該線程,因爲線程被中斷停止。

回答

3

爲了看到線程被中斷,而不是進入休眠方法的第二時間,改變while循環測試在運行方法來檢查中斷標誌:

@Override 
public void run() { 
    while (!Thread.currentThread().isInterrupted()) { 
     try { 
      System.out.println("Sleeping"); 
      Thread.sleep((long) 10000); 
      exitThread(); 
      System.out.println("Processing"); 
     } catch (InterruptedException e) { 
      Thread.currentThread().interrupt(); 
     } 
    } 
} 

線程將休眠狀態,然後設置自己的中斷標誌,然後檢查標誌並終止。只有在設置中斷標誌時線程處於休眠狀態時,Thread#sleep方法纔會拋出InterruptedException。

您的本地布爾變量是不需要的。如果Thread#sleep引發一個InterruptedException異常(在本例中不會因爲線程檢查中斷標誌而離開while循環),那麼中斷標誌將被清除,將其恢復到catch塊允許while測試看到線程中斷。

在實際的程序中,線程會被另一個線程中斷,沒有理由讓線程自行中斷(取而代之)。

1

調用Thread.interrupt()只是爲該線程設置了一個標誌。它什麼都不做。只有阻塞方法(通常是聲明throws InterruptedException)會響應正在設置的標誌(通過拋出)。該標誌是粘性因爲它保持設置直到它被清除。

因此,第一次調用sleep方法正常運行(中斷標誌還沒有設置)。在那之後,你的代碼沒有做任何事情作用於被中斷的狀態,直到第二次循環迭代,其中睡眠呼叫檢測到中斷狀態並拋出異常。

您可以隨時使用Thread.interrupted()或Thread.isInterrupted()檢查中斷狀態(注意,如果已設置,中斷()也會清除中斷狀態)。

1

在這裏你創建另一個線程測試類,但「主」都有自己的線程,讓你創建新的線程進行解釋。 在此代碼中您正在中斷新創建的線程線程-0不是主線程,當您執行此代碼時,它正在使線程在它進入方法睡眠之前exitThread(),因此它正在顯示處理,但如果你試圖把線程睡眠輸入了ExitThread(後),你將有你的答案 如在此代碼:

公共類測試實現Runnable { 公共布爾運行= TRUE;

@Override 
public void run() { 
    while (run) { 

     try { 
      System.out.println("Sleeping..."); 
      exitThread(); 
      Thread.sleep(10000); 
      System.out.println("Processing..."); 
     } catch (InterruptedException e) { 
      System.out.println("Thread intreputted " + e); 
      run = false; 
     } 
    } 
} 

private void exitThread() { 
    Thread.currentThread().interrupt(); 
    if (Thread.currentThread().isInterrupted()) 
     System.out.println(Thread.currentThread().getName() 
       + " is intreputted"); 
    else 
     System.out.println("alive"); 
} 

public static void main(String[] args) { 
    System.out.println("hi I am current thread------>" 
      + Thread.currentThread().getName()); 
    Test test = new Test(); 
    Thread thread = new Thread(test); 
    thread.start(); 
} 

}

希望這將是有益的