Java interrupt()方法使用實例介紹
前言
進入正題之前還是先回顧一個會被問無數(shù)遍的問題:
stop和interrupt的區(qū)別是什么?
簡單的說就是,stop的話,那線程就真的結(jié)束了。
interrupt僅僅只是給線程標記了一下,告訴你說當前線程可以結(jié)束了,你需要自己進行結(jié)束線程。如果你自己不做處理,那這個方法調(diào)用了并看不出效果。
栗子一
不帶sleep等中斷拋異常方法的使用
上代碼:
public class TestClassSenseOne { public static void main(String[] args) throws InterruptedException { TestThread t = new TestThread(); //開啟子線程執(zhí)行 t.start(); //中斷子線程 t.interrupt(); //等待子線程執(zhí)行完畢,t.join() 可以這么理解,誰.join() 誰阻塞當前線程先執(zhí)行自己 t.join(); System.out.println("主線程結(jié)束"); } } class TestThread extends Thread { @Override public void run() { while (!Thread.currentThread().isInterrupted()) { //沒有被標記為中斷狀態(tài)就執(zhí)行,上面start后直接調(diào)用中斷,這句是不會輸出的 System.out.println("我沒有被中斷"); } System.out.println("啊——————————————————————————————斷了。"); } }
運行結(jié)果:
啊——————————————————————————————斷了。
主線程結(jié)束
說明:
上面這段代碼就是,interrupt()的基本用法,子線程TestThread會一直判斷當前線程有沒有被標記為可以中斷了,直到檢查到被標記了,while循環(huán)結(jié)束,子線程任務(wù)結(jié)束。
栗子二
帶sleep的使用
public class TestClassSenseTwo { public static void main(String[] args) throws InterruptedException { TestThreadTwo t = new TestThreadTwo(); //開啟子線程執(zhí)行 t.start(); //模擬真實任務(wù),其實執(zhí)行5秒就執(zhí)行完了,再繼續(xù)等待到20s毫無意義 Thread.sleep(5000); System.out.println("模擬真實任務(wù),其實執(zhí)行5秒就執(zhí)行完了,再繼續(xù)等待到20s毫無意義"); //所以在這里中斷子線程 t.interrupt(); //等待子線程執(zhí)行完畢,t.join() 可以這么理解,誰.join() 誰阻塞當前線程先執(zhí)行自己 t.join(); System.out.println("主線程結(jié)束"); } } class TestThreadTwo extends Thread { @Override public void run() { try { System.out.println("開始執(zhí)行20秒的任務(wù)"); Thread.sleep(20000); System.out.println("線程任務(wù)執(zhí)行完畢"); } catch (InterruptedException e) { System.out.println("線程在sleep的時候被中斷。"); return; } } }
運行結(jié)果:
開始執(zhí)行20秒的任務(wù)
模擬真實任務(wù),其實執(zhí)行5秒就執(zhí)行完了,再繼續(xù)等待到20s毫無意義
線程在sleep的時候被中斷。
主線程結(jié)束
可以看到,這里了結(jié)束子線程的操作輸出是在 catch塊中做的,因為sleep被中斷會拋出InterruptedException異常,同時也會清除當前線程被標記的 可被結(jié)束狀態(tài),如果不在catch塊中結(jié)束,那么interrupt的調(diào)用并不能提前結(jié)束子線程。
大栗子
場景下使用的例子
描述:
我在程序啟動時有一個檢查菜單的任務(wù),這個任務(wù)需要一直被執(zhí)行,直到檢查成功。
思路:
我先定義一個任務(wù)線程類,在其中while (!Thread.currentThread().isInterrupted())
執(zhí)行檢查菜單方法,當檢查菜單方法使用interrupt中斷任務(wù)時說明任務(wù)完成。
上代碼:
檢查方法的Service接口
public interface TestService { void checkMenu() throws InterruptedException; }
實現(xiàn)類
public class TestServiceImpl implements TestService { @Override public void checkMenu() throws InterruptedException { System.out.println("檢查菜單----------->"); //模擬隨機成功與失敗 if (Math.random() * 10 > 4) { //模擬執(zhí)行檢查任務(wù)需要3秒耗時 Thread.sleep(3000); //使用中斷的方式,結(jié)束任務(wù)。 System.out.println("檢查任務(wù)完成******************,checkMenu() 使用interrupt()結(jié)束任務(wù)"); Thread.currentThread().interrupt(); } } }
任務(wù)類
class DoMenuCheckTask extends Thread { @Override public void run() { TestService testService = new TestServiceImpl(); //如果當前線程沒有被中斷,說明 checkMenu 沒有真正成功 while (!Thread.currentThread().isInterrupted()) { try { testService.checkMenu(); /* 下面這兩行的開啟與關(guān)閉,便是兩種結(jié)束當前任務(wù)的方式 1. 這里不使用sleep ,任務(wù)正常被 interrupt 結(jié)束 2. 這里使用 sleep, interrupt打斷的就是 sleep(),打斷sleep會清除isInterrupted中斷狀態(tài), 并拋出 java.lang.InterruptedException: sleep interrupted 異常,所以,不在catch塊中結(jié)束任務(wù), 任務(wù)便無法結(jié)束了。 */ // System.out.println("菜單檢查沒有通過中斷完成任務(wù),休眠5秒后繼續(xù)執(zhí)行----------"); // //如果這里使用了 sleep 那么任務(wù)便是通過下面catch塊中結(jié)束。 // Thread.sleep(5000); } catch (InterruptedException e) { //被中斷,任務(wù)結(jié)束 e.printStackTrace(); System.out.println("菜單檢查通過中斷interrupt成功完成----------->>>>>>>>"); return; } } } }
執(zhí)行
public class SceneExample { public static void main(String[] args) throws InterruptedException { System.out.println("主線程開始執(zhí)行----------->>>>>>>>"); DoMenuCheckTask task = new DoMenuCheckTask(); //開始菜單檢查執(zhí)行任務(wù) task.start(); //讓檢查任務(wù)先執(zhí)行 task.join(); System.out.println("主線程結(jié)束執(zhí)行----------->>>>>>>>"); } }
不使用sleep輸出結(jié)果:
主線程開始執(zhí)行----------->>>>>>>>
檢查菜單----------->
檢查任務(wù)完成******************,checkMenu() 使用interrupt()結(jié)束任務(wù)
主線程結(jié)束執(zhí)行----------->>>>>>>>Process finished with exit code 0
使用sleep的輸出結(jié)果:
主線程開始執(zhí)行----------->>>>>>>>
檢查菜單----------->
檢查任務(wù)完成******************,checkMenu() 使用interrupt()結(jié)束任務(wù)
菜單檢查沒有通過中斷完成任務(wù),休眠5秒后繼續(xù)執(zhí)行----------
菜單檢查通過中斷interrupt成功完成----------->>>>>>>>
主線程結(jié)束執(zhí)行----------->>>>>>>>
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.kusch.demo.test.example.DoMenuCheckTask.run(SceneExample.java:47)Process finished with exit code 0
到此這篇關(guān)于Java interrupt()方法使用實例介紹的文章就介紹到這了,更多相關(guān)Java interrupt()內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringCloud筆記(Hoxton)Netflix之Ribbon負載均衡示例代碼
這篇文章主要介紹了SpringCloud筆記HoxtonNetflix之Ribbon負載均衡,Ribbon是管理HTTP和TCP服務(wù)客戶端的負載均衡器,Ribbon具有一系列帶有名稱的客戶端(Named?Client),對SpringCloud?Ribbon負載均衡相關(guān)知識感興趣的朋友一起看看吧2022-06-06Java 實戰(zhàn)項目之倉庫管理系統(tǒng)的實現(xiàn)流程
讀萬卷書不如行萬里路,只學(xué)書上的理論是遠遠不夠的,只有在實戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用java+SSM+jsp+mysql+maven實現(xiàn)一個倉庫管理系統(tǒng),大家可以在過程中查缺補漏,提升水平2021-11-11Spring DATA JPA 中findAll 進行OrderBy方式
這篇文章主要介紹了Spring DATA JPA 中findAll 進行OrderBy方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11