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

Java線程中斷的實現(xiàn)過程

 更新時間:2025年06月30日 09:00:27   作者:找不到、了  
這篇文章主要介紹了Java線程中斷的實現(xiàn)過程,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

線程的調(diào)度和執(zhí)行由操作系統(tǒng)決定,而 Java 通過提供一系列 API 來與操作系統(tǒng)交互,從而實現(xiàn)對線程的控制。

現(xiàn)代操作系統(tǒng)對線程的控制遵循兩個核心原則:

1、搶占式調(diào)度:操作系統(tǒng)可以強制剝奪線程的 CPU 時間片(如時間片輪轉(zhuǎn)調(diào)度)

2、協(xié)作式中斷:依賴線程主動響應(yīng)中斷信號(Java 的 interrupt())

因此Java 虛擬機(JVM)作為用戶態(tài)程序,其實是無法直接終止一個線程的。當(dāng)我們調(diào)用 thread.stop() 這類方法時,實際上是在用戶態(tài)層面發(fā)出中斷請求,而真正的線程終止還需要操作系統(tǒng)內(nèi)核的配合。

如下圖所示:

Java 線程中斷的三種實現(xiàn)方式:

1、volatile 標(biāo)志位:通過設(shè)置標(biāo)志位,使線程正常退出,能夠確保線程根據(jù)業(yè)務(wù)邏輯安全停止。

2、Thread.stop() 方法:已廢棄,不推薦使用,因為會導(dǎo)致線程安全問題和資源泄漏。

3、Thread.interrupt() 方法:推薦使用,通過設(shè)置中斷標(biāo)志來提示線程停止,能夠優(yōu)雅的停止線程。

1、volatile 標(biāo)志位

volatile關(guān)鍵字可以確保變量的修改對所有線程立即可見。

通過在共享變量上使用volatile,工作線程可以在運行過程中檢查該變量的狀態(tài),一旦檢測到變化即可清理資源并結(jié)束執(zhí)行。

public class WorkerThread extends Thread {
    privatevolatileboolean running = true;
 
    public void run() {
        int i = 1;
        while (running) { // 檢查標(biāo)志位
            System.out.println("線程運行中: " + i++);
            try {
                Thread.sleep(1000L); // 模擬業(yè)務(wù)操作
            } catch (InterruptedException e) {
                // 重新設(shè)置中斷標(biāo)識
                Thread.currentThread().interrupt();
            }
        }
        System.out.println("線程已優(yōu)雅停止");
    }
 
    public void cancel() {
        running = false;
    }
 
    public static void main(String[] args) throws InterruptedException {
        WorkerThread thread = new WorkerThread();
        thread.start();
        // 線程運行一段時間
        Thread.sleep(5000L);
 
        // 修改標(biāo)志位,中斷線程
        thread.cancel();
    }
}

輸出:

運行結(jié)果:

線程運行中: 1
線程運行中: 2
線程運行中: 3
線程運行中: 4
線程運行中: 5
線程已優(yōu)雅停止

2、stop()強制終止

Thread.stop()方法是 Java 早期提供的一種強制中止線程的方式,該方法會立即終止線程,而不執(zhí)行清理工作(如釋放資源、完成文件操作等),因此容易導(dǎo)致資源泄漏和線程安全問題,已被 Java 官方棄用。

public class WorkerThread extends Thread {
    public void run() {
        int i = 1;
        while (true) {
            System.out.println("線程運行中: " + i++);
            try {
                Thread.sleep(1000L); // 模擬業(yè)務(wù)操作
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
 
    public static void main(String[] args) throws InterruptedException {
        WorkerThread thread = new WorkerThread();
        thread.start();
        // 線程運行一段時間
        Thread.sleep(5000L);
 
        // 調(diào)用 stop 方法,強制終止線程
        thread.stop();
        System.out.println("線程已強制終止");
    }
}
運行結(jié)果:

線程運行中: 1
線程運行中: 2
線程運行中: 3
線程運行中: 4
線程運行中: 5
線程已強制終止

為什么 stop() 方法會被廢棄呢? JavaDoc 中Why is Thread.stop deprecated?這篇官方文檔解釋了其被廢棄的原因。

總結(jié)如下:

  • 不可控的資源釋放:線程可能持有鎖或資源,強制終止可能導(dǎo)致資源泄漏。
  • 數(shù)據(jù)不一致:線程可能在執(zhí)行關(guān)鍵操作時被中斷,導(dǎo)致數(shù)據(jù)損壞。
  • 難以調(diào)試:強制終止可能引發(fā)不可預(yù)測的異常。

3、interrupt() 協(xié)作式中斷

因為Thread.stop()中斷線程的粗暴性,Java 官方已經(jīng)廢棄了該方法,那么官方還有沒有其它更優(yōu)雅的方案來中斷線程呢?答案是有的:那就是使用interrupt()協(xié)作式中斷。

什么是協(xié)作式中斷?

協(xié)作式中斷就是區(qū)別于 Thread.stop(),它是非強制且需要配合的。

非強制性:

interrupt() 方法不會強制終止線程,而是通過設(shè)置中斷標(biāo)志來通知線程應(yīng)該停止。線程可以選擇中斷,也可以忽略這個中斷請求,繼續(xù)執(zhí)行。

需要配合:

使用 interrupt() 方法,線程需要主動檢查中斷標(biāo)志,或者在阻塞方法中處理 InterruptedException,才能正常響應(yīng)中斷請求。這種機制是需要線程和中斷請求者之間相互“配合”的。

通過示例來演示下協(xié)作式中斷:

public class WorkerThread extends Thread {
 
    @Override
    public void run() {
        int i = 1;
        while (!Thread.currentThread().isInterrupted()) { // 顯式檢查中斷狀態(tài)
            System.out.println("線程運行中: " + i++);
            try {
                Thread.sleep(1000L); // 模擬業(yè)務(wù)操作
            } catch (InterruptedException e) {
                System.out.println("捕獲到中斷異常,但線程繼續(xù)運行!");
//                Thread.currentThread().interrupt();
            }
        }
        System.out.println("線程已優(yōu)雅停止");
    }
 
    public static void main(String[] args) throws InterruptedException {
        WorkerThread thread = new WorkerThread();
        thread.start();
        Thread.sleep(5000L); // 主線程等待5秒
 
        // 請求線程中斷
        thread.interrupt();
        System.out.println("主線程請求線程中斷");
    }
}
 運行結(jié)果:

線程運行中: 1
線程運行中: 2
線程運行中: 3
線程運行中: 4
線程運行中: 5
主線程請求線程中斷
捕獲到中斷異常,但線程繼續(xù)運行!
線程運行中: 6
線程運行中: 7

可以看到,main() 方法中已經(jīng)請求了線程中斷,但是線程并沒有被中斷,還是繼續(xù)執(zhí)行下去了,為什么?

interrupt() 方法被調(diào)用時,線程的中斷標(biāo)志會被設(shè)置為 true。它的調(diào)用只是傳遞了一個中斷信號,線程本身不會立即停止執(zhí)行。

它需要通過檢查中斷標(biāo)志(如使用 Thread.currentThread().isInterrupted())來決定是否停止當(dāng)線程。

并且當(dāng)線程處于以下阻塞方法(如 sleep()、wait()、join())時,

JVM 會做兩件事:1.拋出 InterruptedException 異常;2.清除中斷標(biāo)志,重新設(shè)置為 false。

那么,當(dāng)我們在程序中捕獲到 InterruptedException 異常時,我們需要做出明確的選擇:

處理異常并終止線程的執(zhí)行;重新設(shè)置中斷標(biāo)識讓上層邏輯感知到。

上邊的示例中,我們在捕獲了 InterruptedException 異常后,這時中斷標(biāo)志已經(jīng)被重置,而程序中卻沒有做任何的處理,導(dǎo)致了在下一輪的循環(huán)判斷中,檢測的中斷狀態(tài)不對,所以線程沒有按預(yù)期執(zhí)行中斷。

正例

public class WorkerThread extends Thread {
 
    @Override
    public void run() {
        int i = 1;
        while (!Thread.currentThread().isInterrupted()) { // 顯式檢查中斷狀態(tài)
            System.out.println("線程運行中: " + i++);
            try {
                Thread.sleep(1000L); // 模擬業(yè)務(wù)操作
            } catch (InterruptedException e) {
                // 重新設(shè)置中斷標(biāo)志,通知上層邏輯進行中斷處理
                System.out.println("線程被中斷!");
                Thread.currentThread().interrupt();
            }
        }
        System.out.println("線程已優(yōu)雅停止");
    }
 
    public static void main(String[] args) throws InterruptedException {
        WorkerThread thread = new WorkerThread();
        thread.start();
        Thread.sleep(5000L); // 主線程等待5秒
 
        // 請求線程中斷
        thread.interrupt();
        System.out.println("主線程請求線程中斷");
    }
}
運行結(jié)果:

線程運行中: 1
線程運行中: 2
線程運行中: 3
線程運行中: 4
線程運行中: 5
主線程請求線程中斷
線程被中斷!
線程已優(yōu)雅停止

在這個示例中,我們在捕獲到異常后,正確的恢復(fù)了中斷標(biāo)志,線程優(yōu)雅地被中斷。

關(guān)于在線程運行狀態(tài)會出現(xiàn)的方法,可參考如下:

總結(jié)

在實際開發(fā)中,推薦使用 volatile 標(biāo)志位和 thread.interrupt() 協(xié)作式中斷來中止線程。這兩種方式能夠確保線程的安全和資源的正確釋放,避免線程不安全和資源泄漏問題。

如下圖所示:

thread.stop() 方法由于其強制性和不安全性,已被廢棄,不推薦使用。通過合理使用協(xié)作式中斷機制,可以實現(xiàn)線程的優(yōu)雅停止,提高程序的健壯性和可靠性。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java如何使用命令查看內(nèi)存占用情況

    Java如何使用命令查看內(nèi)存占用情況

    jhat是一個用于分析Java堆轉(zhuǎn)儲文件的工具,通過啟動Web服務(wù)器并加載堆轉(zhuǎn)儲文件,可以在瀏覽器中查看占用最多內(nèi)存的類及其詳細信息
    2025-02-02
  • SpringData JPA審計功能(@CreatedDate與@LastModifiedDate)實現(xiàn)

    SpringData JPA審計功能(@CreatedDate與@LastModifiedDate)實現(xiàn)

    Spring Data JPA的審計功能提供了一種強大而靈活的機制,用于自動跟蹤實體的創(chuàng)建和修改信息,通過使用@CreatedDate和@LastModifiedDate注解,開發(fā)者可以輕松地實現(xiàn)時間審計,感興趣的可以了解一下
    2025-04-04
  • 關(guān)于解決雪花算法生成的ID傳輸前端后精度丟失問題

    關(guān)于解決雪花算法生成的ID傳輸前端后精度丟失問題

    這篇文章主要介紹了關(guān)于解決雪花算法生成的ID傳輸前端后精度丟失問題,雪花算法生成的ID傳輸?shù)角岸藭r,會出現(xiàn)后三位精度丟失,本文提供了解決思路,需要的朋友可以參考下
    2023-03-03
  • Java的ThreadPoolExecutor業(yè)務(wù)線程池詳細解析

    Java的ThreadPoolExecutor業(yè)務(wù)線程池詳細解析

    這篇文章主要介紹了Java線程池ThreadPoolExecutor詳細解析,任務(wù)剛開始進來的時候就創(chuàng)建核心線程,核心線程滿了會把任務(wù)放到阻塞隊列,阻塞隊列滿了之后才會創(chuàng)建空閑線程,達到最大線程數(shù)之后,再有任務(wù)進來,就只能執(zhí)行拒絕策略了,需要的朋友可以參考下
    2024-01-01
  • Spring Security基于散列加密方案實現(xiàn)自動登錄功能

    Spring Security基于散列加密方案實現(xiàn)自動登錄功能

    為了提高項目的用戶體驗,我們可以在項目中添加自動登錄功能,當(dāng)然也要給用戶提供退出登錄的功能。接下來學(xué)習(xí)下Spring Security基于散列加密方案實現(xiàn)自動登錄功能,一起看看吧
    2021-09-09
  • java集合模擬實現(xiàn)斗地主洗牌和發(fā)牌

    java集合模擬實現(xiàn)斗地主洗牌和發(fā)牌

    這篇文章主要為大家詳細介紹了java集合模擬實現(xiàn)斗地主洗牌和發(fā)牌,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • RestTemplate添加HTTPS證書全過程解析

    RestTemplate添加HTTPS證書全過程解析

    這篇文章主要介紹了RestTemplate添加HTTPS證書全過程,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • @Schedule?如何解決定時任務(wù)推遲執(zhí)行

    @Schedule?如何解決定時任務(wù)推遲執(zhí)行

    這篇文章主要介紹了@Schedule?如何解決定時任務(wù)推遲執(zhí)行問題。具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • Spring定時任務(wù)@Scheduled注解(cron表達式fixedRate?fixedDelay)

    Spring定時任務(wù)@Scheduled注解(cron表達式fixedRate?fixedDelay)

    這篇文章主要為大家介紹了Spring定時任務(wù)@Scheduled注解(cron表達式fixedRate?fixedDelay)使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-11-11
  • feign name指定服務(wù)調(diào)用無效問題及解決

    feign name指定服務(wù)調(diào)用無效問題及解決

    文章主要介紹了FeignClient注解的常用屬性,并通過一個具體的例子說明了為什么某個Feign調(diào)用需要使用url指定路徑才能訪問,最后,文章給出了解決辦法,即使用path屬性指定前綴
    2024-11-11

最新評論

镇原县| 金塔县| 万盛区| 阿合奇县| 定陶县| 肥西县| 昌邑市| 日土县| 五指山市| 海丰县| 彭泽县| 河间市| 明水县| 日照市| 广丰县| 旌德县| 繁峙县| 锦屏县| 米林县| 沂源县| 保康县| 湛江市| 保德县| 昌江| 大同市| 英吉沙县| 新干县| 洛隆县| 牡丹江市| 尉犁县| 慈溪市| 当雄县| 滕州市| 德保县| 扎囊县| 原平市| 巴南区| 通渭县| 白沙| 辉南县| 中牟县|