亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

寫在開頭

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

自然終止有兩種情況:

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

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

start之后,如果線程沒有走到終止狀態(tài),我們該如何停止這個線程呢?

為什么stop終止不可用

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

【源碼解析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());
    }

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

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

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

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

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

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

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

Ok,寫了那么多,我們來寫一個小的demo測試一下線程中斷的方法。

【代碼示例】

public class Test {
    public static void main(String[] args) {
        //測試系統(tǒng)監(jiān)控器
        testSystemMonitor();
    }
 
    /**
     * 測試系統(tǒng)監(jiān)控器
     */
    public static void testSystemMonitor() {
        SystemMonitor sm = new SystemMonitor();
        sm.start();
        try {
            //運行 10 秒后停止監(jiān)控
            Thread.sleep(10 * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("監(jiān)控任務(wù)啟動 10 秒后,停止...");
        sm.stop();
    }
}
/*系統(tǒng)監(jiān)控器*/
class SystemMonitor {
 
    private Thread t;
    //線程中斷標識
    private volatile boolean stop = false;
 
    /**
     * 啟動一個線程監(jiān)控系統(tǒng)
     */
    void start() {
        t = new Thread(() -> {
            while (!stop) {//判斷當前線程是否被打斷
                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)建了一個SystemMonitor類作為系統(tǒng)檢測器,每3秒一循環(huán)的進行檢測,考慮到在Thread.currentThread().isInterrupted()可能在某些情況下中斷失效,所以我們這里自定義一個stop變量,作為線程中斷的標識,檢測線程啟動先對標識位進行判斷。

然后,我們在Test類中寫一個測試方法,調(diào)用這個系統(tǒng)監(jiān)控器,進行檢測,并設(shè)置10秒后,調(diào)用stop方法中斷檢測線程,將中斷標識stop設(shè)置為true。啟動代碼后,我們在控制臺可以看到這樣的輸出:

正在監(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ù)啟動 10 秒后,停止...
任務(wù)執(zhí)行被中斷...

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

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

相關(guān)文章

  • SpringBoot 統(tǒng)一異常處理的實現(xiàn)示例

    SpringBoot 統(tǒng)一異常處理的實現(xiàn)示例

    本文主要介紹了SpringBoot 統(tǒng)一異常處理的實現(xiàn)示例,目的就是在異常發(fā)生時,盡可能地減少破壞,下面就來介紹一下,感興趣的可以了解一下
    2024-07-07
  • 淺談Java中對類的主動引用和被動引用

    淺談Java中對類的主動引用和被動引用

    這篇文章主要介紹了淺談Java中對類的主動引用和被動引用,分享了相關(guān)代碼示例,小編覺得還是挺不錯的,具有一定借鑒價值,需要的朋友可以參考下
    2018-02-02
  • 一文教你如何使用原生的Feign

    一文教你如何使用原生的Feign

    Feign使得 Java HTTP 客戶端編寫更方便,Feign 靈感來源于Retrofit、JAXRS-2.0和WebSocket,這篇文章主要給大家介紹了如何使用原生的Feign的相關(guān)資料,需要的朋友可以參考下
    2021-10-10
  • 使用java執(zhí)行定時任務(wù)示例

    使用java執(zhí)行定時任務(wù)示例

    這篇文章主要介紹了使用java執(zhí)行定時任務(wù)示例,需要的朋友可以參考下
    2014-04-04
  • Java如何處理圖片保存之后變紅色的問題

    Java如何處理圖片保存之后變紅色的問題

    這篇文章主要介紹了Java如何處理圖片保存之后變紅色的問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • 如何基于java向mysql數(shù)據(jù)庫中存取圖片

    如何基于java向mysql數(shù)據(jù)庫中存取圖片

    這篇文章主要介紹了如何基于java向mysql數(shù)據(jù)庫中存取圖片,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-02-02
  • Java程序運行時出現(xiàn)亂碼問題的排查與解決方法

    Java程序運行時出現(xiàn)亂碼問題的排查與解決方法

    本文主要介紹了Java程序運行時出現(xiàn)亂碼問題的排查與解決方法,包括檢查Java源文件編碼、檢查編譯時的編碼設(shè)置、檢查運行時的編碼設(shè)置、檢查命令提示符的代碼頁、檢查命令提示符的字體、檢查 Java 程序的輸出代碼以及檢查環(huán)境變量,需要的朋友可以參考下
    2025-03-03
  • mybatis-plus添加數(shù)據(jù)時id自增問題及解決

    mybatis-plus添加數(shù)據(jù)時id自增問題及解決

    這篇文章主要介紹了mybatis-plus添加數(shù)據(jù)時id自增問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • JAVA設(shè)計模式之訪問者模式原理與用法詳解

    JAVA設(shè)計模式之訪問者模式原理與用法詳解

    這篇文章主要介紹了JAVA設(shè)計模式之訪問者模式,簡單說明了訪問者模式的原理,并結(jié)合實例分析了java訪問者模式的定義與用法,需要的朋友可以參考下
    2017-08-08
  • 一文帶你搞懂SpringBoot中自動裝配原理

    一文帶你搞懂SpringBoot中自動裝配原理

    這篇文章主要為大家詳細介紹了SpringBoot中自動裝配原理的相關(guān)知識,文中的示例代碼講解詳細,具有一定的借鑒價值,有需要的小伙伴可以參考下
    2025-01-01

最新評論