標籤:java
在java的線程Thread類中有三個方法,比較容易混淆,在這裡解釋一下
(1)interrupt:置線程的中斷狀態
(2)isInterrupt:線程是否中斷
(3)interrupted:返回線程的上次的中斷狀態,並清除中斷狀態
舉個例子:
[java] view plaincopy
- 用法:
- class MyThread extends Thread {
- ......
- ......
- public void 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();
- }
- }
- public void 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庫的原始碼中比較常用,因為它既可以得到上一次線程的中斷標誌值,又可以同時清除線程的中斷標誌,一舉兩得,但同時也有壞處,就是這個函數有清除中斷狀態的副作用,不容易理解
java線程中的interrupt,isInterrupt,interrupted方法