Java 執行緒中斷相關方法:interrupt() isInterrupted() interrupted()
阿新 • • 發佈:2022-04-12
interrupt() 方法只是改變中斷狀態而已,它不會中斷一個正在執行的執行緒。如果執行緒被Object.wait, Thread.join和Thread.sleep三種方法之一阻塞,此時呼叫該執行緒的interrupt()方法,那麼該執行緒將丟擲一個 InterruptedException中斷異常。
使用stop方法雖然可以強行終止
正在執行或掛起的執行緒,但使用stop方法是很危險
的,可能會產生不可預料的結果,因此,並不推薦使用stop方法來終止執行緒。Thread.interrupt()方法: 作用是中斷執行緒。將會設定該執行緒的中斷狀態位,即設定為true,中斷的結果執行緒是死亡、還是等待新的任務或是繼續執行至下一步,就取決於這個程式本身。執行緒會不時地檢測這個中斷標示位,以判斷執行緒是否應該被中斷(中斷標示值是否為true)。它並不像stop方法那樣會中斷一個正在執行的執行緒 interrupt()方法只是改變中斷狀態,不會中斷一個正在執行的執行緒。
一旦執行緒的中斷狀態被置為“中斷狀態”,就會丟擲中斷異常。
(1)interrupt:置執行緒的中斷狀態。
(2)isInterrupted:測試執行緒(*呼叫該方法的執行緒*)是否已經中斷,不清除中斷狀態。
(3)interrupted:測試當前執行緒(當前執行緒是指執行interrupted()方法的執行緒)是否已經中斷,且清除中斷狀態。
看原始碼可以得知:interrupted方法底層就是呼叫了清除標誌位的isInterrupted方法。
public boolean isInterrupted() {
return isInterrupted(false);
}
private native boolean isInterrupted(boolean ClearInterrupted);
public static boolean interrupted() {
return currentThread().isInterrupted(true);
}
演示demo:
public class Test { public static void main(String[] args) { /* testWait(); 佔有鎖 interrupt標誌位: false interrupt標誌位: true 執行緒中斷*/ /* testSleep(); interrupt標誌位: false interrupt標誌位: true 執行緒testSleepTread中斷*/ /* testJoin(); Task is interrupted*/ } public static void testSleep() { Runnable testSleepTread = () -> { try { Thread.sleep(1000 * 50); } catch (InterruptedException e) { System.out.println("執行緒testSleepTread中斷"); } }; Thread thread1 = new Thread(testSleepTread); thread1.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("interrupt標誌位: " + thread1.isInterrupted()); thread1.interrupt(); System.out.println("interrupt標誌位: " + thread1.isInterrupted()); } public static void testWait() { Object lock = new Object(); Runnable testWaitTread = () -> { synchronized (lock) { System.out.println("佔有鎖"); try { lock.wait(); } catch (InterruptedException e) { System.out.println("執行緒中斷"); } } }; Thread threadHasLock = new Thread(testWaitTread); threadHasLock.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("interrupt標誌位: " + threadHasLock.isInterrupted()); threadHasLock.interrupt(); System.out.println("interrupt標誌位: " + threadHasLock.isInterrupted()); } public static void testJoin() { Thread thread1 = new Thread(new Task()); thread1.start(); try { thread1.join(); } catch (InterruptedException e) { e.printStackTrace(); } } static class Task implements Runnable { @Override public void run() { try { Thread.currentThread().interrupt(); Thread.sleep(2000); } catch (InterruptedException e) { System.out.println("Task is interrupted"); } } } }