java併發:執行緒中斷
阿新 • • 發佈:2018-11-10
一共三個方法.
Thread.interrupt();//就是嘗試中斷本執行緒.將新增中斷標誌
Thread.isInterrupted();//檢視本執行緒的中斷標誌,代表是否被中斷.
Thread.static.interrupted();//靜態方法,嘗試中斷本執行緒,但是中斷標誌會被清除.
看如下兩段程式碼:
private void aaa() throws InterruptedException { Thread t = new Thread(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().isInterrupted());//false Thread.currentThread().interrupt();//嘗試中斷,新增中斷標誌 System.out.println(Thread.currentThread().isInterrupted());//true } }); t.start(); }
private void bbb() throws InterruptedException { Thread t = new Thread(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().isInterrupted());//false Thread.interrupted();//嘗試中斷,清空中斷標誌 System.out.println(Thread.currentThread().isInterrupted());//false } }); t.start(); }
可以看到他們的區別.
但是一個新的問題產生了.不是中斷了嗎?為什麼後面的列印還可以執行?
好吧.這個得需要看文件.
文件上說了該中斷方法會自上而下判斷,如果符合條件,則執行該措施,且不向下穿透..
1.如果是其他執行緒呼叫該執行緒的中斷,將執行checkAccess()方法,這可能會引起SecurityException.如果是執行緒本身呼叫自身的中斷則沒問題.
2.如果此時執行緒被wait(),join(),sleep()阻塞,那麼將會丟擲異常InterruptedException.中斷狀態清除.但LockSupport.part()沒有說.
3.如果此時執行緒在IO中被阻塞,那麼流通道將關閉,將丟擲 java.nio.channels.ClosedByInterruptException.設定為中斷狀態.
4.如果此時執行緒在java.nio.channels.Selector中阻塞,那麼執行緒將結果立即返回.設定為中斷狀態.
5.如果以上條件都不成立,則設定為中斷狀態.
而我們上面的舉例貌似只有第五條符合,也就是隻是設定為中斷狀態,其他都不會做.
我們再來看一個例子:這個例子就會符合上面第二條.丟擲異常.狀態清除.
其實丟擲異常是終止執行緒的一個不錯的方法.但要記得清理資源.更要注意異常會釋放鎖
private void sleep() throws InterruptedException {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().isInterrupted());//此時還主執行緒在sleep還未執行中斷,false
try {
Thread.currentThread().sleep(20000);//在這裡被中斷,拋異常
System.out.println(Thread.currentThread().isInterrupted());//上句拋異常,這裡就不會執行了.
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().isInterrupted());//中斷標誌被清除,false
e.printStackTrace();
}
}
});
t.start();
Thread.sleep(1000);
t.interrupt();
}
再來個例子,看下io阻塞的情況,實際上這玩意跟上面說的第三個規則根本不一樣
private void read() throws InterruptedException {
Runnable runnable = new Runnable() {
@Override
public void run() {
try {
System.in.read();
} catch (IOException e) {
e.printStackTrace();
}
}
};
Thread t = new Thread(runnable);
t.start();
Thread.sleep(1000);
t.interrupt();//完全沒有用,該被阻塞的還是被阻塞,根本不拋異常.
}
書中好像說了阻塞流和synchronized這倆根本不會受到interrupt()的影響;
還有一個疑問.以上5個規則,一般都是命中第五個,可說第五個只是設定了中斷狀態,有什麼意義呢?
其實可以這樣用.
private void ccc() throws InterruptedException {
Runnable runnable = new Runnable() {
@Override
public synchronized void run() {
while(true){
if (Thread.currentThread().isInterrupted()){
//如果設定為中斷,結束執行
return;
}
//業務程式碼
}
}
};
Thread t = new Thread(runnable);
t.start();
Thread.sleep(3000);
t.interrupt();//命令執行緒中斷執行
}