詳解Java停止線(xiàn)程的四種方法
一、線(xiàn)程停止基礎(chǔ)知識(shí)
- interrupted(): 測(cè)試當(dāng)前線(xiàn)程是否已經(jīng)中斷。該方法為靜態(tài)方法,調(diào)用后會(huì)返回boolean值。不過(guò)調(diào)用之后會(huì)改變線(xiàn)程的狀態(tài),如果是中斷狀態(tài)調(diào)用的,調(diào)用之后會(huì)清除線(xiàn)程的中斷狀態(tài)。
- isInterrupted(): 測(cè)試線(xiàn)程是否已經(jīng)中斷。該方法由對(duì)象調(diào)用
- interrupt(): 標(biāo)記線(xiàn)程為中斷狀態(tài),不過(guò)不會(huì)中斷正在運(yùn)行的線(xiàn)程。
- stop(): 暴力停止線(xiàn)程。已棄用。
二、停止線(xiàn)程方法1:異常法停止
線(xiàn)程調(diào)用interrupt()方法后,在線(xiàn)程的run方法中判斷當(dāng)前對(duì)象的interrupted()狀態(tài),如果是中斷狀態(tài)則拋出異常,達(dá)到中斷線(xiàn)程的效果。
如下示例:
MyThread.java
public class MyThread extends Thread { @Override public void run() { try { for (int i = 0; i < 500000; i++) { if (MyThread.interrupted()){ System.out.println("已經(jīng)是停止?fàn)顟B(tài)了,我要退出了!"); throw new InterruptedException(); } System.out.println("i = " + (i+1)); } System.out.println("如果我被輸出了,則代表線(xiàn)程沒(méi)有停止"); } catch (InterruptedException e) { System.out.println("在MyThread類(lèi)中的run方法中被捕獲"); e.printStackTrace(); } } }
Main.java
/** * 根據(jù)中斷狀態(tài)退出for循環(huán) * @Author: xjf * @Date: 2019/5/25 13:27 */ public class Main { public static void main(String[] args) { try { MyThread myThread = new MyThread(); myThread.start(); Thread.sleep(100); myThread.interrupt(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("end!"); } }
結(jié)果如下:
i = 19115
i = 19116
i = 19117
i = 19118
i = 19119
end!
已經(jīng)是停止?fàn)顟B(tài)了,我要退出了!
在MyThread類(lèi)中的run方法中被捕獲
java.lang.InterruptedException
at com.book.interrupt_exit.MyThread.run(MyThread.java:15)Process finished with exit code 0
三、停止線(xiàn)程方法2:在沉睡中停止
先將線(xiàn)程sleep,然后調(diào)用interrupt標(biāo)記中斷狀態(tài),interrupt會(huì)將阻塞狀態(tài)的線(xiàn)程中斷。會(huì)拋出中斷異常,達(dá)到停止線(xiàn)程的效果。如下示例:
MyThread.java
public class MyThread extends Thread { @Override public void run() { try { System.out.println("run-----------start"); Thread.sleep(5000); System.out.println("run-----------end"); } catch (InterruptedException e) { System.out.println("在沉睡中被停止!進(jìn)入catch,線(xiàn)程的是否處于停止?fàn)顟B(tài):" + this.isInterrupted()); e.printStackTrace(); } } }
Main.java
public class Main { public static void main(String[] args) { try { MyThread myThread = new MyThread(); myThread.start(); Thread.sleep(2000); System.out.println("狀態(tài):"+MyThread.interrupted()); myThread.interrupt(); } catch (InterruptedException e) { e.printStackTrace(); } } }
結(jié)果
run-----------start
狀態(tài):false
java.lang.InterruptedException: sleep interrupted
在沉睡中被停止!進(jìn)入catch,線(xiàn)程的是否處于停止?fàn)顟B(tài):false
at java.lang.Thread.sleep(Native Method)
at com.book.sleep_interrupt.MyThread.run(MyThread.java:13)
線(xiàn)程先調(diào)用interrupt標(biāo)記中斷狀態(tài),然后線(xiàn)程再睡眠。會(huì)拋出中斷異常,達(dá)到停止線(xiàn)程的效果。如下:
MyThread1.java
public class MyThread1 extends Thread { @Override public void run() { try { for (int i = 0; i < 100000; i++) { System.out.println("i = " + (i+1)); } System.out.println("run begin"); //interrupt是做一個(gè)中斷標(biāo)記,當(dāng)時(shí)不會(huì)去中斷正在運(yùn)行的線(xiàn)程,當(dāng)該線(xiàn)程處于阻塞狀態(tài)時(shí)就會(huì)進(jìn)行中斷 //因此,先進(jìn)行interrupt后,再遇到sleep阻塞時(shí),才會(huì)進(jìn)行中斷 Thread.sleep(200000); System.out.println("run end"); } catch (InterruptedException e) { System.out.println("先停止,再遇到了sleep! 進(jìn)入catch!"); e.printStackTrace(); } } }
Main1.java
public class Main1 { public static void main(String[] args) { MyThread1 myThread1 = new MyThread1(); myThread1.start(); myThread1.interrupt(); System.out.println("end!"); } }
結(jié)果:
i = 99993
i = 99994
i = 99995
i = 99996
i = 99997
i = 99998
i = 99999
i = 100000
run begin
先停止,再遇到了sleep! 進(jìn)入catch!
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.book.sleep_interrupt.MyThread1.run(MyThread1.java:19)
四、停止線(xiàn)程方法3:stop()暴力停止
線(xiàn)程調(diào)用stop()方法會(huì)被暴力停止,方法已棄用。該方法會(huì)有不好的后果:
- 強(qiáng)制讓線(xiàn)程停止有可能使一些請(qǐng)理性的工作得不到完成。
- 對(duì)鎖定的對(duì)象進(jìn)行了“解鎖”,導(dǎo)致數(shù)據(jù)得不到同步的處理,出現(xiàn)數(shù)據(jù)不一致的問(wèn)題(比如一個(gè)方法加上了synchronized,并在其中進(jìn)行了一個(gè)長(zhǎng)時(shí)間的處理,而在處理結(jié)束之前該線(xiàn)程進(jìn)行了stop(),則未完成的數(shù)據(jù)將沒(méi)有進(jìn)行到同步的處理)
五、停止線(xiàn)程方法4:使用return停止線(xiàn)程
調(diào)用interrupt標(biāo)記為中斷狀態(tài)后,在run方法中判斷當(dāng)前線(xiàn)程狀態(tài),如果為中斷狀態(tài)則return,能達(dá)到停止線(xiàn)程的效果。
備注:建議使用“拋異常”的方法來(lái)實(shí)現(xiàn)線(xiàn)程的停止,因?yàn)樵赾atch塊中還可以將異常向上拋,使線(xiàn)程停止的事件得以傳播
參考:《Java多線(xiàn)程編程核心技術(shù)》
到此這篇關(guān)于詳解Java停止線(xiàn)程的四種方法的文章就介紹到這了,更多相關(guān)Java停止線(xiàn)程內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用Mybatis-Plus實(shí)現(xiàn)對(duì)象屬性自動(dòng)填充功能
這篇文章主要介紹了如何使用Mybatis-Plus實(shí)現(xiàn)對(duì)象屬性自動(dòng)填充功能,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,感興趣的朋友們下面隨著小編來(lái)一起來(lái)學(xué)習(xí)吧2024-01-01springmvc配置線(xiàn)程池Executor做多線(xiàn)程并發(fā)操作的代碼實(shí)例
今天小編就為大家分享一篇關(guān)于springmvc配置線(xiàn)程池Executor做多線(xiàn)程并發(fā)操作的代碼實(shí)例,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-03-03寧可用Lombok也不把成員設(shè)置為public原理解析
這篇文章主要為大家介紹了寧可用Lombok也不把成員設(shè)置為public原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03模仿mybatis-plus實(shí)現(xiàn)rpc調(diào)用
這篇文章主要為大家介紹了模仿mybatis-plus實(shí)現(xiàn)rpc調(diào)用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02Java Agent 動(dòng)態(tài)修改字節(jié)碼詳情
這篇文章主要介紹了Java Agent動(dòng)態(tài)修改字節(jié)碼的相關(guān)資料,需要的朋友可以參考下面文章具體的內(nèi)容2021-09-09mybatis Invalid bound statement(not foun
這篇文章主要介紹了mybatis Invalid bound statement(not found)排坑記錄,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-06-06java Object轉(zhuǎn)byte與byte轉(zhuǎn)Object方式
這篇文章主要介紹了java Object轉(zhuǎn)byte與byte轉(zhuǎn)Object方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08