java interrupt()方法只是設定線程的中斷標記,當對處於阻塞狀態的線程調用interrupt方法時(處於阻塞狀態的線程是調用sleep, wait, join 的線程),會拋出InterruptException異常,而這個異常會清除中斷標記。因此,根據這兩個思路,不同的run()方法設計,會導致不同的結果,下面是樣本,並說明了運行了結果和原因
package com.concurrency;import java.util.concurrent.TimeUnit;public class Test{ public static void main(String[] args) throws InterruptedException { RunTest rt = new RunTest(); Thread t = new Thread(rt); t.start(); TimeUnit.SECONDS.sleep(2); t.interrupt(); }}//不同的run方法設計class RunTest implements Runnable{ //這種設計比較好,當調用阻塞操作時,會因為拋出異常退出,當不調用阻塞操作時,會因為檢查中斷狀態而退出 public void run1(){ try{ while(!Thread.interrupted()){ // System.out.println("sleep 5s"); //Thread.sleep(5000);接收到中斷訊號時,由於while迴圈判斷不成立退出,不拋出異常 } System.out.println("Exit normal"); }catch(Exception e){ System.out.println("interrupted"); } } public void run5() { try{ while(!Thread.interrupted()){ // System.out.println("sleep 5s"); Thread.sleep(5000);//接收到中斷訊號時,由於拋出異常退出,類比耗時操作 } System.out.println("Exit normal"); }catch(Exception e){ System.out.println("interrupted and exit"); } } public void run3(){ while(!Thread.interrupted()){ //接收到中斷訊號時,由於while迴圈判斷不成立退出 } System.out.println("interrupt normal and exit 2"); } //此種設計不好 public void run4(){ while(!Thread.interrupted()){ try{ TimeUnit.SECONDS.sleep(1); //接收到中斷訊號,捕獲異常並清除中斷狀態,所以不退出,所以這種不是良好的設計方式,如果想要退出,需要在catch語句中Thread.currentThread().interrupt(); }catch(Exception e){ System.out.println("Interrupte and clear interrupt status, so run continue"); } } System.out.println("exit normal 3"); } public void run(){ double d = 1; while(!Thread.interrupted()){ while(d<3000){ d = d + (Math.PI+Math.E)/d; System.out.println(d+ " running"); //接收到中斷訊號時,不會中斷正在啟動並執行操作,只有當操作完成後,檢查中斷狀態時會退出 } } System.out.println("Exit "+d); }}
可以將run()改為上面其中的一個,對比看看運行結果,如上面所述。