標籤:extends 死迴圈 方法 ++i 線程 完全 class 檢驗 一個
使用interrupt()中斷線程
當一個線程運行時,另一個線程可以調用對應的Thread對象的interrupt()方法來中斷它,該方法只是在目標線程中設定一個標誌,表示它已經被中斷,並立即返回。這裡需要注意的是,如果只是單純的調用interrupt()方法,線程並沒有實際被中斷,會繼續往下執行。
public class InterruptTest { public static void main(String[] args) throws InterruptedException { MyThread t = new MyThread("MyThread"); t.start(); Thread.sleep(100);// 睡眠100毫秒 t.interrupt();// 中斷t線程 } } class MyThread extends Thread { int i = 0; public MyThread(String name) { super(name); } public void run() { while(true) {// 死迴圈,等待被中斷 System.out.println(getName() + getId() + "執行了" + ++i + "次"); } } }
運行後,我們發現,線程t一直在執行,沒有被中斷,原來interrupt()是騙人的,汗!其實interrupt()方法並不是中斷線程的執行,而是為調用該方法的線程對象打上一個標記,設定其中斷狀態為true,通過isInterrupted()方法可以得到這個線程狀態,我們將上面的程式做一個小改動:
public class InterruptTest { public static void main(String[] args) throws InterruptedException { MyThread t = new MyThread("MyThread"); t.start(); Thread.sleep(100);// 睡眠100毫秒 t.interrupt();// 中斷t線程 } } class MyThread extends Thread { int i = 0; public MyThread(String name) { super(name); } public void run() { while(!isInterrupted()) {// 當前線程沒有被中斷,則執行 System.out.println(getName() + getId() + "執行了" + ++i + "次"); } } }
這樣的話,線程被順利的中斷執行了。很多人實現一個線程類時,都會再加一個flag標記,以便控制線程停止執行,其實完全沒必要,通過線程自身的中斷狀態,就可以完美實現該功能。如果線程在調用 Object 類的 wait()、wait(long) 或 wait(long, int) 方法,或者該類的 join()、join(long)、join(long, int)、sleep(long) 或 sleep(long, int) 方法過程中受阻,則其中斷狀態將被清除,它還將收到一個 InterruptedException。 我們可以捕獲該異常,並且做一些處理。另外,Thread.interrupted()方法是一個靜態方法,它是判斷當前線程的中斷狀態,需要注意的是,線程的中斷狀態會由該方法清除。換句話說,如果連續兩次調用該方法,則第二次調用將返回 false(在第一次調用已清除了其中斷狀態之後,且第二次調用檢驗完中斷狀態前,當前線程再次中斷的情況除外)。
(4) java線程中斷