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

Java線程中斷的實(shí)現(xiàn)過(guò)程

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

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

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

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

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

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

如下圖所示:

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

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

2、Thread.stop() 方法:已廢棄,不推薦使用,因?yàn)闀?huì)導(dǎo)致線程安全問(wèn)題和資源泄漏。

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

1、volatile 標(biāo)志位

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

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

public class WorkerThread extends Thread {
    privatevolatileboolean running = true;
 
    public void run() {
        int i = 1;
        while (running) { // 檢查標(biāo)志位
            System.out.println("線程運(yùn)行中: " + i++);
            try {
                Thread.sleep(1000L); // 模擬業(yè)務(wù)操作
            } catch (InterruptedException e) {
                // 重新設(shè)置中斷標(biāo)識(shí)
                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();
        // 線程運(yùn)行一段時(shí)間
        Thread.sleep(5000L);
 
        // 修改標(biāo)志位,中斷線程
        thread.cancel();
    }
}

輸出:

運(yùn)行結(jié)果:

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

2、stop()強(qiáng)制終止

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

public class WorkerThread extends Thread {
    public void run() {
        int i = 1;
        while (true) {
            System.out.println("線程運(yùn)行中: " + 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();
        // 線程運(yùn)行一段時(shí)間
        Thread.sleep(5000L);
 
        // 調(diào)用 stop 方法,強(qiáng)制終止線程
        thread.stop();
        System.out.println("線程已強(qiáng)制終止");
    }
}
運(yùn)行結(jié)果:

線程運(yùn)行中: 1
線程運(yùn)行中: 2
線程運(yùn)行中: 3
線程運(yùn)行中: 4
線程運(yùn)行中: 5
線程已強(qiáng)制終止

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

總結(jié)如下:

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

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

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

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

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

非強(qiáng)制性:

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

需要配合:

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

通過(guò)示例來(lái)演示下協(xié)作式中斷:

public class WorkerThread extends Thread {
 
    @Override
    public void run() {
        int i = 1;
        while (!Thread.currentThread().isInterrupted()) { // 顯式檢查中斷狀態(tài)
            System.out.println("線程運(yùn)行中: " + i++);
            try {
                Thread.sleep(1000L); // 模擬業(yè)務(wù)操作
            } catch (InterruptedException e) {
                System.out.println("捕獲到中斷異常,但線程繼續(xù)運(yùn)行!");
//                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秒
 
        // 請(qǐng)求線程中斷
        thread.interrupt();
        System.out.println("主線程請(qǐng)求線程中斷");
    }
}
 運(yùn)行結(jié)果:

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

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

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

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

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

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

那么,當(dāng)我們?cè)诔绦蛑胁东@到 InterruptedException 異常時(shí),我們需要做出明確的選擇:

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

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

正例

public class WorkerThread extends Thread {
 
    @Override
    public void run() {
        int i = 1;
        while (!Thread.currentThread().isInterrupted()) { // 顯式檢查中斷狀態(tài)
            System.out.println("線程運(yùn)行中: " + i++);
            try {
                Thread.sleep(1000L); // 模擬業(yè)務(wù)操作
            } catch (InterruptedException e) {
                // 重新設(shè)置中斷標(biāo)志,通知上層邏輯進(jìn)行中斷處理
                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秒
 
        // 請(qǐng)求線程中斷
        thread.interrupt();
        System.out.println("主線程請(qǐng)求線程中斷");
    }
}
運(yùn)行結(jié)果:

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

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

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

總結(jié)

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

如下圖所示:

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

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

相關(guān)文章

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

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

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

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

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

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

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

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

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

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

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

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

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

    RestTemplate添加HTTPS證書(shū)全過(guò)程解析

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

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

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

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

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

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

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

最新評(píng)論

沽源县| 锦屏县| 龙泉市| 宕昌县| 临猗县| 清远市| 华宁县| 临夏县| 广平县| 奉贤区| 张家港市| 崇州市| 堆龙德庆县| 璧山县| 聂荣县| 嘉义县| 大关县| 江孜县| 富宁县| 华亭县| 佳木斯市| 黄梅县| 宜兴市| 绥德县| 中江县| 阜阳市| 麻栗坡县| 察哈| 大英县| 辉南县| 察雅县| 高安市| 库伦旗| 康马县| 镇江市| 名山县| 长岭县| 新野县| 和硕县| 平武县| 新蔡县|