java執行緒中的interrupt,isInterrupt,interrupted方法
阿新 • • 發佈:2019-02-03
在java的執行緒Thread類中有三個方法,比較容易混淆,在這裡解釋一下
(1)interrupt:置執行緒的中斷狀態
(2)isInterrupt:執行緒是否中斷
(3)interrupted:返回執行緒的上次的中斷狀態,並清除中斷狀態
舉個例子:
一般來說,阻塞函式,如:Thread.sleep、Thread.join、Object.wait、LockSupport.park等在檢查到執行緒的中斷狀態時,會丟擲InterruptedException,同時會清除執行緒的中斷狀態
對於InterruptedException的處理,可以有兩種情況:
(1)外層程式碼可以處理這個異常,直接丟擲這個異常即可
(2)如果不能丟擲這個異常,比如在run()方法內,因為在得到這個異常的同時,執行緒的中斷狀態已經被清除了,需要保留執行緒的中斷狀態,則需要呼叫Thread.currentThread().interrupt()
另外,Thread.interrupted()在jdk庫的原始碼中比較常用,因為它既可以得到上一次執行緒的中斷標誌值,又可以同時清除執行緒的中斷標誌,一舉兩得,但同時也有壞處,就是這個函式有清除中斷狀態的副作用,不容易理解
(1)interrupt:置執行緒的中斷狀態
(2)isInterrupt:執行緒是否中斷
(3)interrupted:返回執行緒的上次的中斷狀態,並清除中斷狀態
舉個例子:
- 用法:
- class MyThread extends Thread {
- ......
- ......
- publicvoid run() {
- try {
- while(!Thread.currentThread().isInterrupted()) {
- //當達到佇列容量時,在這裡會阻塞
- //put的內部會呼叫LockSupport.park()這個是用來阻塞執行緒的方法
- //當其他執行緒,呼叫此執行緒的interrupt()方法時,會設定一箇中斷標誌
- //LockSupport.part()中檢測到這個中斷標誌,會丟擲InterruptedException,並清除執行緒的中斷標誌
- //因此在異常段呼叫Thread.currentThread().isInterrupted()返回為false
- ArrayBlockingQueue.put(somevalue);
- }
- } catch (InterruptedException e) {
- //由於阻塞庫函式,如:Object.wait,Thread.sleep除了丟擲異常外,還會清除執行緒中斷狀態,因此可能在這裡要保留執行緒的中斷狀態
- Thread.currentThread().interrupt();
- }
- }
- publicvoid cancel() {
- interrupt();
- }
- }
- 外部呼叫
- MyThread thread = new MyThread();
- thread.start();
- ......
- thread.cancel();
- thread.isInterrupted();
一般來說,阻塞函式,如:Thread.sleep、Thread.join、Object.wait、LockSupport.park等在檢查到執行緒的中斷狀態時,會丟擲InterruptedException,同時會清除執行緒的中斷狀態
對於InterruptedException的處理,可以有兩種情況:
(1)外層程式碼可以處理這個異常,直接丟擲這個異常即可
(2)如果不能丟擲這個異常,比如在run()方法內,因為在得到這個異常的同時,執行緒的中斷狀態已經被清除了,需要保留執行緒的中斷狀態,則需要呼叫Thread.currentThread().interrupt()
另外,Thread.interrupted()在jdk庫的原始碼中比較常用,因為它既可以得到上一次執行緒的中斷標誌值,又可以同時清除執行緒的中斷標誌,一舉兩得,但同時也有壞處,就是這個函式有清除中斷狀態的副作用,不容易理解