java 兩階段終止線程的正確做法
一、怎麼優雅地關閉一個線程?
在一個線程T1中如何優雅地關閉線程T2(也就是說要給T2一個機會釋放持有的資源)?
1.錯誤做法
使用stop()方法停止線程:
stop()
方法會真正殺死線程,如果此時該線程持有鎖,那麼其他線程將永遠無法獲取鎖。
使用System.exit()方法停止線程:
會讓整個進程都退出
2.正確做法
思路:
代碼實現:
public class Test { public static void main(String[] args) throws InterruptedException { TwoPhaseTermination twoPhaseTermination = new TwoPhaseTermination(); twoPhaseTermination.start(); Thread.sleep(3000); twoPhaseTermination.stop(); } } class TwoPhaseTermination{ // 監控線程 private Thread monitorThread; public void start(){ monitorThread = new Thread(()->{ Thread current = Thread.currentThread(); while(true){ if(current.isInterrupted()){ System.out.println("線程要關閉瞭..."); break; } try { Thread.sleep(1000); // 階段1 System.out.println("監控線程正在工作...."); // 階段2 // 如果在階段2被打斷,線程的isInterrupted標志位為true,會捕抓到信號並關閉線程 // 如果在階段1被打斷,會進入catch語句塊,並且isInterrupted標志位清空,無法關閉線程 } catch (InterruptedException e) { e.printStackTrace(); // 需要重新設置isInterrupted標志位為true monitorThread.interrupt(); } } }); // 啟動線程 monitorThread.start(); } public void stop(){ // 設置isInterrupted標志位true monitorThread.interrupt(); } }
運行結果:
兩階段關閉線程:
二、要點
為什麼需要在catch代碼塊中重新執行monitorThread.interrupt()?
因為Thread.sleep()
執行過程中被打斷,isInterrupted標志位會清空,下一次進入while
循環就會忽略這次打斷,繼續運行線程。
演示一下把monitorThread.interrupt()註釋掉的結果:
可以看到,會忽略這次的isInterrupted信號,繼續運行線程。
到此這篇關於java 兩階段終止線程的正確做法的文章就介紹到這瞭,更多相關java 兩階段終止線程內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!