淺析java線程中斷的辦法
中斷線程相關(guān)的方法
中斷線程有一些相應(yīng)的方法,這里列出來(lái)一下。
注意,如果是Thread.method(),則代表是靜態(tài)方法。如果是thread.method()則代表著是類方法
void thread.stop()
這個(gè)方法能中斷正在運(yùn)行的線程,但是已經(jīng)不推薦使用了,在將來(lái)的版本或許棄用,因?yàn)閺?qiáng)行中斷運(yùn)行中的線程,是不安全的。
void thread.interrupt()
如果正在運(yùn)行wait(),sleep(),join()這三個(gè)方法阻塞了線程,那么將會(huì)使得線程拋出InterruptedException異常,這是一個(gè)中斷阻塞的過程。如果是其它的正在運(yùn)行的狀態(tài),那么將不會(huì)有任何影響,也不會(huì)中斷線程,或者拋出異常,只會(huì)會(huì)打上一個(gè)中斷線程的標(biāo)志,是否中斷線程,將由程序控制。
boolean thread.isInterrupted()
它會(huì)獲取當(dāng)前線程的標(biāo)志,如果之前調(diào)用過thread.interrupt(),那么它的返回值是true。它的作用就是返回該線程是否有中斷標(biāo)志。多次調(diào)用這個(gè)方法的結(jié)果是一樣的。
void Thread.interrupted()
與前面的方法不一樣的是,這是一個(gè)靜態(tài)方法,代表著不需要拿到線程對(duì)象就可以直接執(zhí)行,所以它的作用是返回當(dāng)前線程是否有中斷標(biāo)志。但是它的區(qū)別是,當(dāng)調(diào)用這個(gè)方法之后,會(huì)清除程序的中斷標(biāo)志,就是如果當(dāng)前線程已中斷,第一次調(diào)用這個(gè)方法的返回值是true,第二次調(diào)用這個(gè)方法的返回值為false,因?yàn)檎{(diào)用方法時(shí),會(huì)清除它的中斷標(biāo)志。
中斷線程
for循環(huán)標(biāo)記退出
package com.xiaojiezhu.thread; /** * @author xiaojie.zhu */ public class ThreadBreak implements Runnable { @Override public void run() { for(int i = 0 ; i < 10000 ; i ++){ boolean interruped = Thread.currentThread().isInterrupted(); if(interruped){ //有中斷標(biāo)記,中斷 break; } System.out.println(i); } System.out.println("over"); } public static void main(String[] args) throws InterruptedException { Thread t = new Thread(new ThreadBreak()); t.start(); Thread.sleep(1); t.interrupt(); } }
打印結(jié)果如下
44
45
46
47
over
阻塞的退出線程
只要是在運(yùn)行wait(),sleep(),join()的方法,它就會(huì)聲明一個(gè)InterruptedException異常,也就是意味著這些方法并不是一定能執(zhí)行完成,因?yàn)楫?dāng)調(diào)用線程的interrupt()方法時(shí),就會(huì)中斷這個(gè)阻塞的辦法,從而進(jìn)入到異常中,代碼如下
package com.xiaojiezhu.thread; /** * @author xiaojie.zhu */ public class ThreadBreak2 implements Runnable { @Override public void run() { try { Thread.sleep(20000); System.out.println("這段話不會(huì)輸出"); } catch (InterruptedException e) { //如果在sleep()的過程中調(diào)用了interrupt()方法,就會(huì)進(jìn)入這里,因?yàn)闀?huì)強(qiáng)行中斷sleep() //這里打印出來(lái)的中斷標(biāo)記為false,因?yàn)橹灰M(jìn)入了InterruptedException異常,中斷標(biāo)記就會(huì)被清除掉 System.out.println("中斷標(biāo)記為:" + Thread.currentThread().isInterrupted()); System.out.println("輸出異常"); e.printStackTrace(); } } public static void main(String[] args) throws InterruptedException { Thread t = new Thread(new ThreadBreak2()); t.start(); Thread.sleep(100); t.interrupt(); System.out.println("over"); } }
打印結(jié)果如下
over
中斷標(biāo)記為:false
輸出異常
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.xiaojiezhu.thread.ThreadBreak2.run(ThreadBreak2.java:10)
at java.lang.Thread.run(Thread.java:748)
注意:因?yàn)橹灰M(jìn)入了InterruptedException異常,中斷標(biāo)記就會(huì)被清除掉
這里會(huì)衍生出另一種情況,就是如果在進(jìn)入阻塞方法之前,就有了中斷標(biāo)記呢?會(huì)發(fā)生什么,就如下的代碼:
for(int i = 0 ; i < 10000 ; i ++){ System.out.println(i); } try { System.out.println("開始sleep"); Thread.sleep(20000); System.out.println("結(jié)束sleep"); } catch (InterruptedException e) { e.printStackTrace(); }
實(shí)際上它會(huì)先執(zhí)行完上面的for循環(huán),因?yàn)閒or循環(huán)中是無(wú)法中止的,在進(jìn)入sleep()的時(shí)候,瞬間就拋出異常
完整的測(cè)試代碼如下
package com.xiaojiezhu.thread; /** * @author xiaojie.zhu */ public class ThreadBreak3 implements Runnable { @Override public void run() { for(int i = 0 ; i < 10000 ; i ++){ System.out.println(i); } try { System.out.println("開始sleep"); Thread.sleep(20000); System.out.println("結(jié)束sleep"); } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) { Thread thread = new Thread(new ThreadBreak3()); thread.start(); thread.interrupt(); } }
打印結(jié)果如下
9997 9998 9999 開始sleep java.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at com.xiaojiezhu.thread.ThreadBreak3.run(ThreadBreak3.java:15) at java.lang.Thread.run(Thread.java:748)
使用stop()方法停止線程
thread.stop()方法是一個(gè)不安全的方法,已經(jīng)不推薦使用了,但是在目前的代碼中,還能正常使用,我們不推薦這樣使用,但是這里介紹一下
package com.xiaojiezhu.thread; /** * @author xiaojie.zhu */ public class ThreadBreak4 implements Runnable { @Override public void run() { System.out.println("進(jìn)入線程"); try { Thread.sleep(20000); System.out.println("結(jié)束線程"); } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) { Thread t = new Thread(new ThreadBreak4()); t.start(); try { Thread.sleep(200); t.stop(); System.out.println("over"); } catch (InterruptedException e) { e.printStackTrace(); } } }
打印結(jié)果如下
進(jìn)入線程
over
相關(guān)文章
JS只能輸入正整數(shù)的簡(jiǎn)單實(shí)例
下面小編就為大家?guī)?lái)一篇JS只能輸入正整數(shù)的簡(jiǎn)單實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧2016-10-10微信小程序scroll-view實(shí)現(xiàn)橫向滾動(dòng)和上拉加載示例
本篇文章主要介紹了微信小程序scroll-view實(shí)現(xiàn)橫向滾動(dòng)和上拉加載示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-03-03Javascript實(shí)現(xiàn)蘋果懸浮虛擬按鈕
本文給大家分享的是使用javascript實(shí)現(xiàn)仿制蘋果的懸浮虛擬按鈕的代碼,非常的簡(jiǎn)單,給大家一個(gè)思路,大家可以根據(jù)自己的情況自由擴(kuò)展。2016-04-04淺談Webpack4 plugins 實(shí)現(xiàn)原理
在wabpack 核心功能除了loader應(yīng)該就是plugins插件了,本文主要介紹了Webpack4 plugins 實(shí)現(xiàn)原理,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09JS之判斷是否為對(duì)象或數(shù)組的幾種方式總結(jié)
這篇文章主要介紹了JS之判斷是否為對(duì)象或數(shù)組的幾種方式總結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04javascript中利用柯里化函數(shù)實(shí)現(xiàn)bind方法【推薦】
下面小編就為大家?guī)?lái)一篇javascript中利用柯里化函數(shù)實(shí)現(xiàn)bind方法【推薦】。小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考,一起跟隨小編過來(lái)看看吧2016-04-04使用jscript實(shí)現(xiàn)二進(jìn)制讀寫腳本代碼
Reading And Writing Binary Files Using JScript正如我剛才推什么我能做的JScript中,我想出了對(duì)問題的二進(jìn)制文件。以下級(jí)的解決,這為小到中等大小的文件。我的部分包括這個(gè)職位在這里,因?yàn)槲壹磳⒏吨T表決,在一個(gè)職位約發(fā)送帶有附件的電郵通過JScript和它會(huì)使用這個(gè)二進(jìn)制文件碼來(lái)讀取,在二進(jìn)制附件檔案。2008-06-06Threejs實(shí)現(xiàn)滴滴官網(wǎng)首頁(yè)地球動(dòng)畫功能
這篇文章主要介紹了Threejs實(shí)現(xiàn)滴滴官網(wǎng)首頁(yè)地球動(dòng)畫效果,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07