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

一文帶你徹底搞懂Java中線程的中斷與優(yōu)雅停止

 更新時(shí)間:2026年05月29日 09:06:30   作者:身如柳絮隨風(fēng)揚(yáng)  
在多線程編程中,如何安全、優(yōu)雅地停止一個(gè)線程是一個(gè)經(jīng)典而又容易出錯(cuò)的話題,本文將帶你深入理解 Java 的中斷模型,掌握 interrupt()、interrupted()、isInterrupted() 的區(qū)別與用法,并對(duì)比三種常見的停止線程方式

1. 引言

在多線程編程中,如何安全、優(yōu)雅地停止一個(gè)線程是一個(gè)經(jīng)典而又容易出錯(cuò)的話題。Thread 類提供的 stop()、suspend() 等方法早已被廢棄,因?yàn)樗鼈儚?qiáng)行終止線程可能導(dǎo)致資源泄露或數(shù)據(jù)不一致。那么,正確的姿勢(shì)是什么?答案就是——協(xié)作式中斷機(jī)制

本文將帶你深入理解 Java 的中斷模型,掌握 interrupt()、interrupted()isInterrupted() 的區(qū)別與用法,并對(duì)比三種常見的停止線程方式:volatile 標(biāo)志位、AtomicBoolean 以及中斷機(jī)制。通過流程圖和代碼示例,幫你徹底掌握線程的優(yōu)雅關(guān)閉技巧。

2. 線程中斷機(jī)制核心概念

Java 中的中斷并不是真正“打斷”線程,而是設(shè)置一個(gè)中斷標(biāo)志位,由目標(biāo)線程自行檢查該標(biāo)志并決定如何響應(yīng)。這是一種協(xié)作式的取消機(jī)制。

2.1 中斷相關(guān)方法

方法作用是否清除中斷狀態(tài)
void interrupt()將調(diào)用線程的中斷標(biāo)志設(shè)為 true(如果線程處于阻塞狀態(tài),則會(huì)拋出 InterruptedException 并清除標(biāo)志)阻塞時(shí)清除
boolean isInterrupted()返回當(dāng)前線程的中斷狀態(tài),不改變標(biāo)志
static boolean interrupted()返回當(dāng)前線程的中斷狀態(tài),并清除標(biāo)志(設(shè)為 false

2.2 中斷狀態(tài)流轉(zhuǎn)圖

2.3 阻塞方法的中斷響應(yīng)

當(dāng)線程處于 Object.wait()、Thread.sleep()、Thread.join() 等阻塞狀態(tài)時(shí),調(diào)用 interrupt() 會(huì)立即拋出 InterruptedException,并清除中斷標(biāo)志。因此,在 catch 塊中如果需要保留中斷狀態(tài),必須再次調(diào)用 interrupt()。

try {
    Thread.sleep(1000);
} catch (InterruptedException e) {
    // 重新設(shè)置中斷標(biāo)志,讓上層邏輯感知
    Thread.currentThread().interrupt();
    // 或者直接退出線程
    return;
}

3. 三種優(yōu)雅停止線程的方式

3.1 方式一:volatile 布爾標(biāo)志位

利用 volatile 保證內(nèi)存可見性,在循環(huán)中檢查標(biāo)志位,適合不涉及阻塞操作的場(chǎng)景。

public class VolatileStopDemo implements Runnable {
    private volatile boolean running = true;

    @Override
    public void run() {
        while (running) {
            // 執(zhí)行任務(wù)
        }
        System.out.println("線程結(jié)束");
    }

    public void stop() {
        running = false;
    }
}

優(yōu)點(diǎn):簡單直觀。

缺點(diǎn):若線程處于 sleepwait 等阻塞狀態(tài),無法立即響應(yīng)。

3.2 方式二:AtomicBoolean

volatile 類似,但提供原子性的 getAndSet 等操作,適合需要安全修改標(biāo)志的場(chǎng)景。

public class AtomicStopDemo implements Runnable {
    private AtomicBoolean running = new AtomicBoolean(true);

    @Override
    public void run() {
        while (running.get()) {
            // 執(zhí)行任務(wù)
        }
    }

    public void stop() {
        running.set(false);
    }
}

3.3 方式三:中斷標(biāo)志(推薦)

利用 interrupt() + 檢查 isInterrupted(),能夠同時(shí)響應(yīng)阻塞狀態(tài)和非阻塞狀態(tài)。

public class InterruptStopDemo implements Runnable {
    @Override
    public void run() {
        // 循環(huán)中檢查中斷標(biāo)志
        while (!Thread.currentThread().isInterrupted()) {
            try {
                // 可能阻塞的操作
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // 收到中斷異常后,退出循環(huán)
                Thread.currentThread().interrupt(); // 重置標(biāo)志(可選)
                break;
            }
        }
        System.out.println("線程通過中斷停止");
    }

    public void stop() {
        Thread.currentThread().interrupt();
    }
}

4. 三種停止方式對(duì)比

特性volatile 標(biāo)志AtomicBoolean中斷標(biāo)志
能否喚醒阻塞線程否(無法打斷 sleep/wait)是(會(huì)拋出 InterruptedException)
是否支持清除狀態(tài)需手動(dòng)復(fù)位需手動(dòng)復(fù)位提供 interrupted() 清除
典型應(yīng)用場(chǎng)景簡單輪詢?nèi)蝿?wù)并發(fā)修改標(biāo)志通用,尤其含阻塞操作
推薦程度適合阻塞少的場(chǎng)景適合需要原子讀寫的場(chǎng)景最推薦,Java 原生協(xié)作機(jī)制

5. 常見誤區(qū)與最佳實(shí)踐

誤區(qū):interrupt()會(huì)立即終止線程

錯(cuò)。它只是發(fā)了個(gè)“信號(hào)”,線程需要自己配合檢查才能停止。

誤區(qū):捕獲InterruptedException后中斷標(biāo)志自動(dòng)恢復(fù)

半對(duì)。異常被拋出時(shí)中斷標(biāo)志被清除,但你可以手動(dòng)重置。

誤區(qū):interrupted()和isInterrupted()一樣

錯(cuò)interrupted() 會(huì)清除標(biāo)志,而 isInterrupted() 不改變。

最佳實(shí)踐

  • RunnableThreadrun() 方法中,始終通過 while(!isInterrupted())while(running) 循環(huán)執(zhí)行。
  • 如果調(diào)用了可中斷的阻塞方法,一定要處理 InterruptedException,并在異常后重新設(shè)置中斷標(biāo)志或退出。
  • 不要吞掉 InterruptedException(即 catch 后啥也不干),這會(huì)導(dǎo)致中斷信號(hào)丟失。
  • 在封裝庫或框架時(shí),優(yōu)先使用中斷機(jī)制而非自定義標(biāo)志,以便與 Java 并發(fā)工具類(如 ExecutorServiceshutdownNow())兼容。

6. 完整示例:線程池中的中斷處理

ExecutorService executor = Executors.newSingleThreadExecutor();
Future<?> future = executor.submit(() -> {
    while (!Thread.currentThread().isInterrupted()) {
        System.out.println("working...");
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            System.out.println("收到中斷,退出");
            Thread.currentThread().interrupt(); // 重置標(biāo)志
            break;
        }
    }
});

// 停止線程(兩種方式)
// 方式1:優(yōu)雅關(guān)閉(等待任務(wù)完成)
executor.shutdown();
// 方式2:立即中斷
executor.shutdownNow();   // 內(nèi)部會(huì)調(diào)用 interrupt()

7. 總結(jié)

  • 中斷是 Java 推薦的線程停止協(xié)作機(jī)制,通過 interrupt() 設(shè)置標(biāo)志,線程自行檢查并退出。
  • 三種停止方式各有適用場(chǎng)景,但中斷機(jī)制最通用,能同時(shí)處理阻塞和非阻塞代碼。
  • 牢記 interrupted() 會(huì)清除中斷狀態(tài),而 isInterrupted() 不會(huì)。
  • 在處理 InterruptedException 時(shí),要么退出線程,要么重新設(shè)置中斷標(biāo)志。

一句話總結(jié):停止線程不是“暴力殺死”,而是“禮貌請(qǐng)退”。掌握中斷,讓你的多線程程序更加健壯、可維護(hù)。

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

相關(guān)文章

  • 如何讓W(xué)in10實(shí)現(xiàn)Java文件的開機(jī)自啟動(dòng)

    如何讓W(xué)in10實(shí)現(xiàn)Java文件的開機(jī)自啟動(dòng)

    這篇文章主要介紹了如何讓W(xué)in10實(shí)現(xiàn)Java文件的開機(jī)自啟動(dòng),對(duì)于一些想要一直運(yùn)行的Java文件,就會(huì)造成每次系統(tǒng)更新之后的重啟導(dǎo)致Java文件無法繼續(xù)運(yùn)行。,需要的朋友可以參考下
    2019-06-06
  • java LocalDateTime加時(shí)間,計(jì)算兩個(gè)時(shí)間的差方式

    java LocalDateTime加時(shí)間,計(jì)算兩個(gè)時(shí)間的差方式

    文章介紹了如何在Java中使用LocalDateTime類添加時(shí)間并計(jì)算兩個(gè)時(shí)間的差值,通過比較來總結(jié)個(gè)人經(jīng)驗(yàn),并鼓勵(lì)讀者參考和支持腳本之家
    2025-03-03
  • mybatis 使用jdbc.properties文件設(shè)置不起作用的解決方法

    mybatis 使用jdbc.properties文件設(shè)置不起作用的解決方法

    這篇文章主要介紹了mybatis 使用jdbc.properties文件設(shè)置不起作用的解決方法,需要的朋友可以參考下
    2018-03-03
  • 解決nacos升級(jí)spring cloud 2020.0無法使用bootstrap.yml的問題

    解決nacos升級(jí)spring cloud 2020.0無法使用bootstrap.yml的問題

    這篇文章主要介紹了解決nacos升級(jí)spring cloud 2020.0無法使用bootstrap.yml的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • SpringBoot集成Open WebUI實(shí)現(xiàn)AI流式對(duì)話

    SpringBoot集成Open WebUI實(shí)現(xiàn)AI流式對(duì)話

    本文介紹如何在 Spring Boot 項(xiàng)目中集成 Open WebUI,通過自動(dòng)管理用戶 Token、調(diào)用 OpenAI Java SDK,實(shí)現(xiàn) SSE 流式輸出,并與前端文本輸入框無縫對(duì)接,為業(yè)務(wù)系統(tǒng)注入 AI 能力,需要的朋友可以參考下
    2026-05-05
  • java中的switch case語句使用詳解

    java中的switch case語句使用詳解

    這篇文章主要介紹了java中的switch case語句使用詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • 讓IntelliJ IDEA支持.vue文件的方法

    讓IntelliJ IDEA支持.vue文件的方法

    這篇文章主要介紹了讓IntelliJ IDEA支持.vue文件的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-05-05
  • MyBatis使用<foreach>標(biāo)簽報(bào)錯(cuò)問題及解決

    MyBatis使用<foreach>標(biāo)簽報(bào)錯(cuò)問題及解決

    這篇文章主要介紹了MyBatis使用<foreach>標(biāo)簽報(bào)錯(cuò)問題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • ElasticSearch添加索引代碼實(shí)例解析

    ElasticSearch添加索引代碼實(shí)例解析

    這篇文章主要介紹了ElasticSearch添加索引代碼實(shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • 解決Idea的選擇文件后定位瞄準(zhǔn)器"Select Opened File"的功能不見了

    解決Idea的選擇文件后定位瞄準(zhǔn)器"Select Opened File"的功能

    使用IntelliJ IDEA時(shí),可能會(huì)發(fā)現(xiàn)"SelectOpenedFile"功能不見了,這個(gè)功能允許用戶快速定位到當(dāng)前打開文件的位置,若要找回此功能,只需在IDEA的標(biāo)題欄上右鍵,然后選擇"Always Select Opened File",這樣就可以重新啟用這個(gè)便捷的功能
    2024-11-11

最新評(píng)論

东丽区| 平果县| 宁陕县| 丰都县| 文化| 轮台县| 大洼县| 长葛市| 秭归县| 龙井市| 中西区| 南木林县| 长葛市| 长葛市| 西青区| 霞浦县| 霞浦县| 格尔木市| 黄龙县| 兰考县| 丰宁| 南丹县| 西盟| 大连市| 漯河市| 文山县| 富锦市| 威海市| 礼泉县| 北京市| 阿鲁科尔沁旗| 沈阳市| 南召县| 聊城市| 望都县| 合作市| 花莲市| 蕉岭县| 漳州市| 芒康县| 浪卡子县|