Java如何優雅得終止線程?使用兩階段終止模式
在一個線程 T1 中如何“優雅”終止線程 T2?這裏的【優雅】指的是給 T2 一個"料理後事""的機會,即讓T2完成善後工作後終止
錯誤思路
-
使用stop()
stop方法會直接殺死線程,如果這時線程鎖住了共享資源,那麼當它被殺死後就再也沒有機會釋放鎖,
其它線程將永遠無法獲取鎖
-
使用 System.exit(int) 方法停止線程
目的僅是停止一個線程,但這種做法會讓整個程序都停止
兩階段終止模式
流程圖:
方法之
利用 isInterrupted()
interrupt 可以打斷正在執行的線程,無論這個線程是在 sleep,wait,還是正常運行
public class TestTwoPhaseTermination {
public static void main(String[] args) throws InterruptedException {
TPTInterrupt t = new TPTInterrupt() ;
t.start();//啓動線程
Thread.sleep(3500);
System.out.println("to stop");
t.stop(); //實際上是interrupt
}
}
class TPTInterrupt {
private Thread thread;
public void start(){
thread = new Thread(() -> {
while(true) {
Thread current = Thread.currentThread();
if(current.isInterrupted()) {
System.out.println(current.getName()+":料理後事");
break;
}
try {
Thread.sleep(1000);
System.out.println(current.getName()+":保存結果");
} catch (InterruptedException e) {
current.interrupt(); //發生異常,打斷並設置標記
}
}
},"監控線程");
thread.start();
}
public void stop() {
thread.interrupt();
}
}
執行結果:
方法二:設置類屬性用來表示是否執行了stop方法,該屬性添加volatile保證可見性,監控線程循環判斷該屬性即可,較簡單,不上代碼了