Thread執行緒終止interrupt
interrupt()的字面意思是中斷一個執行緒,那麼它是怎麼使用來達到中斷當前執行緒的呢?我們來看幾個例子。
一、終止處於“阻塞狀態”的執行緒
透過中斷方式終止處於阻塞狀態的執行緒,當執行緒由於被呼叫了sleep(),wait(),join()等方法而進入阻塞狀態,此時呼叫執行緒的interrupt()將執行緒的中斷標記為true。由於處於阻塞狀態,中斷標記會被清除,同時產生一個InterruptedException
異常,將InterruptedException
放在適當的位置就能終止執行緒
@Overridepublic void run() { try { while (true) { // 執行任務... } } catch (InterruptedException ie) { // 由於產生InterruptedException異常,退出while(true)迴圈,執行緒終止! } }
說明:
在
while(true)
中不斷的執行任務,當執行緒處於阻塞狀態時,呼叫執行緒的interrupt()
方法會產生InterruptedException
中斷,中斷的捕獲在while(true)
之外,這樣就退出了while(true)
迴圈。
對InterruptException
的捕獲一定要放在while(true)
迴圈體的外面,這樣產生異常時就退出了while(true)
迴圈,否則,InterruptException
在while(true)
迴圈體之外,就需要額外的新增退出處理,形式如下:
@Overridepublic void run() { while (true) { try { // 執行任務... } catch (InterruptedException ie) { // InterruptedException在while(true)迴圈體內。 // 當執行緒產生了InterruptedException異常時,while(true)仍能繼續執行!需要手動退出 break; } } }
上面的
InterruptedException
異常的捕獲是在while(true)
中,當產生異常被catch
時,仍然在while(true)
迴圈體內,要退出while(true)
迴圈體,需要額外的執行操作。
二、終止處於執行狀態的執行緒
透過標記方式終止處於執行狀態的執行緒,其中,包括“中斷標記”和“額外新增標記”
(1)透過“中斷標記”終止執行緒,形式如下:
@Overridepublic void run() { while (!isInterrupted()) { // 執行任務... } }
說明:
isInterrupted()
是判斷執行緒的中斷標記是不是為true,當前執行緒處於執行狀態,並且我們需要終止它時,可以呼叫執行緒的interrupt()
方法,使用執行緒的中斷標記為true,即isInterrupted()
會返回true
,此時,就會退出while
迴圈。interrupt()
並不會終止處於“執行狀態”的執行緒,它會將執行緒的中斷標記設為true
(2)透過“額外新增標記”,形式如下:
rivate volatile boolean flag= true; protected void stopTask() { flag = false; }@Overridepublic void run() { while (flag) { // 執行任務... } }
說明:
執行緒中有一個
flag
標記,它的預設值是true
,並且我們提供stopTask()
來設定flag
標記,當我們需要終止該執行緒時,呼叫該執行緒的stopTask()
方法就可以讓執行緒退出while迴圈
。其中將flag定義為volatile
型別,保證flag
的可見性,其他執行緒透過stopTask()
修改了flag
之後,本執行緒能看到修改後的flag
的值。
綜合終止處於“阻塞狀態”和“執行狀態”的終止方式。
@Overridepublic void run() { try { // 1. isInterrupted()保證,只要中斷標記為true就終止執行緒。 while (!isInterrupted()) { // 執行任務... } } catch (InterruptedException ie) { // 2. InterruptedException異常保證,當InterruptedException異常產生時,執行緒被終止。 } }
三、終止執行緒的示例
interrupt()
常常被用來終止“阻塞狀態”執行緒,參考示例:
class MyThread extends Thread { public MyThread(String name) { super(name); } @Override public void run() { try { int i=0; while (!isInterrupted()) { System.out.println("thread is running"); Thread.sleep(100); // 休眠100ms i++; System.out.println(Thread.currentThread().getName()+" ("+this.getState()+") loop " + i); } } catch (InterruptedException e) { System.out.println(Thread.currentThread().getName() +" ("+this.getState()+") catch InterruptedException."); } } }public class Hello { public static void main(String[] args) { try { Thread t1 = new MyThread("t1"); // 新建“執行緒t1” System.out.println(t1.getName() +" ("+t1.getState()+") is new."); t1.start(); // 啟動“執行緒t1” System.out.println(t1.getName() +" ("+t1.getState()+") is started."); // 主執行緒休眠300ms,然後主執行緒給t1發“中斷”指令。 System.out.println("MainThread sleep"); Thread.sleep(300); System.out.println("Thread interrupt"); t1.interrupt(); System.out.println(t1.getName() +" ("+t1.getState()+") is interrupted."); // 主執行緒休眠300ms,然後檢視t1的狀態。 System.out.println("MainThread sleep"); Thread.sleep(300); System.out.println(t1.getName() +" ("+t1.getState()+") is interrupted now."); } catch (InterruptedException e) { e.printStackTrace(); } } }
執行結果:
t1 (NEW) is new. t1 (RUNNABLE) is started. MainThread sleep thread is running t1 (RUNNABLE) loop 1thread is running t1 (RUNNABLE) loop 2thread is running t1 (RUNNABLE) loop 3thread is running Thread interrupt t1 (TIMED_WAITING) is interrupted. MainThread sleep t1 (RUNNABLE) catch InterruptedException. t1 (TERMINATED) is interrupted now.
結果說明:
(1)主執行緒main中會透過new MyThread("t1")建立執行緒t1,之後透過t1.start()啟動執行緒t1
(2)t1啟動之後,會不斷的檢查他的中斷標記,如果中斷標記為false,則休眠100ms
(3)t1休眠之後會切換到主執行緒main,主執行緒再次執行時,會執行t1.interrupt()中斷執行緒t1。t1收到中斷指令之後,會將t1的中斷標誌設定為false,而且會丟擲InterruptedException
異常,在t1的run()方法中,是在迴圈體之外捕獲的異常,因此迴圈被終止。
透過“額外新增標記”的方式終止“執行狀態”的執行緒的示例:
class MyThread extends Thread { private volatile boolean flag= true; public void stopTask() { flag = false; } public MyThread(String name) { super(name); } @Override public void run() { synchronized(this) { try { int i=0; while (flag) { Thread.sleep(100); // 休眠100ms i++; System.out.println(Thread.currentThread().getName()+" ("+this.getState()+") loop " + i); } } catch (InterruptedException ie) { System.out.println(Thread.currentThread().getName() +" ("+this.getState()+") catch InterruptedException."); } } } }public class Hello { public static void main(String[] args) { try { MyThread t1 = new MyThread("t1"); // 新建“執行緒t1” System.out.println(t1.getName() +" ("+t1.getState()+") is new."); t1.start(); // 啟動“執行緒t1” System.out.println(t1.getName() +" ("+t1.getState()+") is started."); // 主執行緒休眠300ms,然後主執行緒給t1發“中斷”指令。 Thread.sleep(300); System.out.println("stopTask"); t1.stopTask(); System.out.println(t1.getName() +" ("+t1.getState()+") is interrupted."); // 主執行緒休眠300ms,然後檢視t1的狀態。 Thread.sleep(300); System.out.println(t1.getName() +" ("+t1.getState()+") is interrupted now."); } catch (InterruptedException e) { e.printStackTrace(); } } }
interrupted()
和isInterrupted()
都能夠用於檢測物件的“中斷標記”,區別是interrupted()
除了返回中斷標記外,它還會清除中斷標記(即將中斷標記設為false),而isInterrupted()
僅僅返回中斷標記,關於這兩個方法的詳細解釋請看後續文章。
作者:激情的狼王
連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/3016/viewspace-2809661/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Thread interrupt() 執行緒中斷的詳細說明thread執行緒
- 執行緒的基本操作:新建和終止執行緒執行緒
- Java之 join 等待執行緒終止Java執行緒
- 終止java執行緒的2種方法Java執行緒
- Thread(執行緒)thread執行緒
- 如何"優雅"地終止一個執行緒?執行緒
- 併發程式設計——如何終止執行緒程式設計執行緒
- 【雜談】執行緒中斷——Interrupt執行緒
- Java的Interrupt與執行緒中斷Java執行緒
- Thinking in Java---如何正確的終止子執行緒ThinkingJava執行緒
- java 多執行緒之使用 interrupt 停止執行緒的幾種方法Java執行緒
- Java實現終止執行緒池中正在執行的定時任務Java執行緒
- thread.Interrupt()與thread.Abort()thread
- new Thread與執行緒建立thread執行緒
- Java 中的執行緒 threadJava執行緒thread
- JNI-從jvm原始碼分析Thread.interrupt的系統級別執行緒打斷原理JVM原始碼thread執行緒
- Thread的interrupt機制thread
- java多執行緒之Thread類Java執行緒thread
- Java多執行緒(二):Thread類Java執行緒thread
- Java多執行緒Thread類使用Java執行緒thread
- 一. 執行緒管理之Thread基礎執行緒thread
- 多執行緒系列(二)之Thread類執行緒thread
- Thread執行緒知識點講解thread執行緒
- 【 Thread】建立執行緒的2種方法thread執行緒
- Java 執行緒中斷(interrupt)與阻塞 (park)的區別Java執行緒
- Swift多執行緒:使用Thread進行多執行緒間通訊,協調子執行緒任務Swift執行緒thread
- subprocess.Popen 如何提前終止程式執行
- Java多執行緒之Thread原始碼分析Java執行緒thread原始碼
- @Java | Thread & synchronized – [ 執行緒同步鎖 基本使用]Javathreadsynchronized執行緒
- c# 執行緒Thread的IsBackground屬性C#執行緒thread
- java.lang.Thread中守護執行緒Javathread執行緒
- 終止expdp正在執行中的匯出任務
- Thread 中的 join() 方法的作用是呼叫執行緒等待該執行緒執行完後,再繼續執行thread執行緒
- python多執行緒之從Thread類繼承Python執行緒thread繼承
- Python多執行緒之_thread與threading模組Python執行緒thread
- java 多執行緒(關於Thread的講解)Java執行緒thread
- 132.繼承Thread實現多執行緒繼承thread執行緒
- 多執行緒設計模式之Worker Thread模式執行緒設計模式thread