最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺析在Java中如何優(yōu)雅的停止一個(gè)線程

 更新時(shí)間:2024年03月13日 14:15:42   作者:JavaBuild  
我們知道在Java中可以通過(guò)new Thread().start()創(chuàng)建一個(gè)線程,那今天我們就來(lái)思考另外一個(gè)問(wèn)題:線程的終止,快跟隨小編一起學(xué)習(xí)起來(lái)吧

寫在開頭

經(jīng)過(guò)上幾篇博文的學(xué)習(xí),我們知道在Java中可以通過(guò)new Thread().start()創(chuàng)建一個(gè)線程,那今天我們就來(lái)思考另外一個(gè)問(wèn)題:線程的終止

自然終止有兩種情況:

1. 線程的任務(wù)執(zhí)行完成;

2. 線程在執(zhí)行任務(wù)過(guò)程中發(fā)生異常。

start之后,如果線程沒有走到終止?fàn)顟B(tài),我們?cè)撊绾瓮V惯@個(gè)線程呢?

為什么stop終止不可用

翻看Thread源碼后,發(fā)現(xiàn)其提供過(guò)一個(gè)stop()方法,可以用來(lái)終止線程,我們看一下它的源碼。

【源碼解析1】

@Deprecated
    public final void stop() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            checkAccess();
            if (this != Thread.currentThread()) {
                security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
            }
        }
        // A zero status value corresponds to "NEW", it can't change to
        // not-NEW because we hold the lock.
        if (threadStatus != 0) {
            resume(); // Wake up thread if it was suspended; no-op otherwise
        }
 
        // The VM can handle all thread states
        stop0(new ThreadDeath());
    }

這個(gè)方法使用了@Deprecated修飾,代表著它是廢棄的方法,在Java的編碼規(guī)約中,過(guò)時(shí)的方法不建議繼續(xù)使用,并且在這個(gè)方法的注釋中官方也提示說(shuō)這是一個(gè)不安全的強(qiáng)制惡意中斷方法,會(huì)破壞線程的原子性

因此,在這里強(qiáng)烈建議大家不要再用stop方法去停止線程了!

如何優(yōu)雅的停止一個(gè)線程

我們知道線程只有從 runnable 狀態(tài)(可運(yùn)行/運(yùn)行狀態(tài)) 才能進(jìn)入terminated 狀態(tài)(終止?fàn)顟B(tài)),如果線程處于 blocked、waiting、timed_waiting 狀態(tài)(休眠狀態(tài)),就需要通過(guò) Thread 類的 interrupt() 方法,讓線程從休眠狀態(tài)進(jìn)入 runnable 狀態(tài),從而結(jié)束線程。

這里就涉及到了一個(gè)概念“線程中斷”,這是一種協(xié)作機(jī)制,當(dāng)其他線程通知需要被中斷的線程后,線程中斷的狀態(tài)被設(shè)置為 true,但是具體被要求中斷的線程要怎么處理,完全由被中斷線程自己決定,可以在合適的時(shí)機(jī)中斷請(qǐng)求,也可以完全不處理繼續(xù)執(zhí)行下去,這樣一來(lái),安全性就得到了保障。

Thread類中提供線程中斷的方法如下:

  • Thread.interrupt():中斷線程。這里的中斷線程并不會(huì)立即停止線程,而是設(shè)置線程的中斷狀態(tài)為 true(默認(rèn)是 flase);
  • Thread.currentThread().isInterrupted():測(cè)試當(dāng)前線程是否被中斷。線程的中斷狀態(tài)會(huì)受這個(gè)方法的影響,調(diào)用一次可以使線程中斷狀態(tài)變?yōu)?true,調(diào)用兩次會(huì)使這個(gè)線程的中斷狀態(tài)重新轉(zhuǎn)為 false;
  • Thread.isInterrupted():測(cè)試當(dāng)前線程是否被中斷。與上面方法不同的是調(diào)用這個(gè)方法并不會(huì)影響線程的中斷狀態(tài)。

Ok,寫了那么多,我們來(lái)寫一個(gè)小的demo測(cè)試一下線程中斷的方法。

【代碼示例】

public class Test {
    public static void main(String[] args) {
        //測(cè)試系統(tǒng)監(jiān)控器
        testSystemMonitor();
    }
 
    /**
     * 測(cè)試系統(tǒng)監(jiān)控器
     */
    public static void testSystemMonitor() {
        SystemMonitor sm = new SystemMonitor();
        sm.start();
        try {
            //運(yùn)行 10 秒后停止監(jiān)控
            Thread.sleep(10 * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("監(jiān)控任務(wù)啟動(dòng) 10 秒后,停止...");
        sm.stop();
    }
}
/*系統(tǒng)監(jiān)控器*/
class SystemMonitor {
 
    private Thread t;
    //線程中斷標(biāo)識(shí)
    private volatile boolean stop = false;
 
    /**
     * 啟動(dòng)一個(gè)線程監(jiān)控系統(tǒng)
     */
    void start() {
        t = new Thread(() -> {
            while (!stop) {//判斷當(dāng)前線程是否被打斷
                System.out.println("正在監(jiān)控系統(tǒng)...");
                try {
                    Thread.sleep(3 * 1000L);//執(zhí)行 3 秒
                    System.out.println("任務(wù)執(zhí)行 3 秒");
                    System.out.println("監(jiān)控的系統(tǒng)正常!");
                } catch (InterruptedException e) {
                    System.out.println("任務(wù)執(zhí)行被中斷...");
                    //重新設(shè)置線程為中斷狀態(tài),保證JVM拋異常情況下,中斷狀態(tài)仍為true。
                    Thread.currentThread().interrupt();
                }
            }
        });
        t.start();
    }
    //線程中斷
    void stop() {
        stop = true;
        t.interrupt();
    }
}

在這里我們先創(chuàng)建了一個(gè)SystemMonitor類作為系統(tǒng)檢測(cè)器,每3秒一循環(huán)的進(jìn)行檢測(cè),考慮到在Thread.currentThread().isInterrupted()可能在某些情況下中斷失效,所以我們這里自定義一個(gè)stop變量,作為線程中斷的標(biāo)識(shí),檢測(cè)線程啟動(dòng)先對(duì)標(biāo)識(shí)位進(jìn)行判斷。

然后,我們?cè)赥est類中寫一個(gè)測(cè)試方法,調(diào)用這個(gè)系統(tǒng)監(jiān)控器,進(jìn)行檢測(cè),并設(shè)置10秒后,調(diào)用stop方法中斷檢測(cè)線程,將中斷標(biāo)識(shí)stop設(shè)置為true。啟動(dòng)代碼后,我們?cè)诳刂婆_(tái)可以看到這樣的輸出:

正在監(jiān)控系統(tǒng)...
任務(wù)執(zhí)行 3 秒
監(jiān)控的系統(tǒng)正常!
正在監(jiān)控系統(tǒng)...
任務(wù)執(zhí)行 3 秒
監(jiān)控的系統(tǒng)正常!
正在監(jiān)控系統(tǒng)...
任務(wù)執(zhí)行 3 秒
監(jiān)控的系統(tǒng)正常!
正在監(jiān)控系統(tǒng)...
監(jiān)控任務(wù)啟動(dòng) 10 秒后,停止...
任務(wù)執(zhí)行被中斷...

與我們的預(yù)期一樣,監(jiān)控線程在執(zhí)行了3個(gè)循環(huán)的檢測(cè)任務(wù)后,被成功中斷調(diào)。到這里,我們就成功的、安全的、優(yōu)雅的停止了一個(gè)線程啦!

到此這篇關(guān)于淺析在Java中如何優(yōu)雅的停止一個(gè)線程的文章就介紹到這了,更多相關(guān)Java停止線程內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring?+?ECharts實(shí)現(xiàn)數(shù)據(jù)可視化的案例詳解

    Spring?+?ECharts實(shí)現(xiàn)數(shù)據(jù)可視化的案例詳解

    Apache?ECharts是一個(gè)基于?JavaScript?的開源可視化圖表庫(kù),在網(wǎng)頁(yè)上實(shí)現(xiàn)數(shù)據(jù)的可視化,非常好用,本文將通過(guò)一個(gè)簡(jiǎn)單的demo來(lái)給大家介紹一下Spring?+?ECharts如何數(shù)據(jù)可視化,需要的朋友可以參考下
    2023-07-07
  • SpringBoot利用自定義注解實(shí)現(xiàn)多數(shù)據(jù)源

    SpringBoot利用自定義注解實(shí)現(xiàn)多數(shù)據(jù)源

    這篇文章主要為大家詳細(xì)介紹了SpringBoot如何利用自定義注解實(shí)現(xiàn)多數(shù)據(jù)源效果,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以了解一下
    2022-10-10
  • Springboot傳參詳解

    Springboot傳參詳解

    這篇文章主要介紹了Springboot傳參的相關(guān)知識(shí),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2023-11-11
  • Spring Boot 項(xiàng)目開發(fā)全流程實(shí)戰(zhàn)示例總結(jié)

    Spring Boot 項(xiàng)目開發(fā)全流程實(shí)戰(zhàn)示例總結(jié)

    本文詳細(xì)介紹了SpringBoot項(xiàng)目的開發(fā)流程,從實(shí)體類定義到Controller接口開放,涵蓋了代碼注釋、核心概念圖解及高頻面試題,通過(guò)實(shí)際操作,展示了如何實(shí)現(xiàn)用戶增刪改查功能,感興趣的朋友跟隨小編一起看看吧
    2026-01-01
  • 使用opencsv文件讀寫CSV文件

    使用opencsv文件讀寫CSV文件

    這篇文章主要為大家詳細(xì)介紹了用opencsv文件讀寫CSV文件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-05-05
  • 帶你了解JAVA中的一些鎖概念

    帶你了解JAVA中的一些鎖概念

    今天小編就為大家分享一篇關(guān)于Java分布式鎖的概念與實(shí)現(xiàn)方式詳解,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2021-08-08
  • mybatis?查詢方式與效率高低對(duì)比

    mybatis?查詢方式與效率高低對(duì)比

    這篇文章主要介紹了mybatis?查詢方式與效率高低對(duì)比,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • SpringBoot異步方法捕捉異常詳解

    SpringBoot異步方法捕捉異常詳解

    這篇文章主要為大家詳細(xì)介紹了SpringBoot異步方法捕捉異常,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-09-09
  • java 輸出九九乘法表口訣的代碼

    java 輸出九九乘法表口訣的代碼

    這篇文章主要介紹了java 輸出9*9口訣的代碼,需要的朋友可以參考下
    2017-02-02
  • Mabatis錯(cuò)誤提示Parameter index out of range的處理方法

    Mabatis錯(cuò)誤提示Parameter index out of range的處理方法

    這篇文章主要介紹了Mabatis錯(cuò)誤提示Parameter index out of range 的處理方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-08-08

最新評(píng)論

乐亭县| 松阳县| 奉新县| 余庆县| 渭源县| 和顺县| 拜城县| 青阳县| 伊川县| 达日县| 马公市| 莫力| 杂多县| 建德市| 舞阳县| 肃北| 崇义县| 双桥区| 平和县| 青铜峡市| 呼伦贝尔市| 南川市| 新建县| 景洪市| 五指山市| 乐亭县| 都兰县| 咸丰县| 新巴尔虎左旗| 安远县| 家居| 诸暨市| 青河县| 榆社县| 应城市| 滨州市| 六安市| 依安县| 弥勒县| 阜城县| 岚皋县|