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

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

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

1. 引言

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

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

2. 線程中斷機制核心概念

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

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

方法作用是否清除中斷狀態(tài)
void interrupt()將調(diào)用線程的中斷標(biāo)志設(shè)為 true(如果線程處于阻塞狀態(tài),則會拋出 InterruptedException 并清除標(biāo)志)阻塞時清除
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)時,調(diào)用 interrupt() 會立即拋出 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)志位,適合不涉及阻塞操作的場景。

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)點:簡單直觀。

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

3.2 方式二:AtomicBoolean

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

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(),能夠同時響應(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. 三種停止方式對比

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

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

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

。它只是發(fā)了個“信號”,線程需要自己配合檢查才能停止。

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

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

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

。interrupted()清除標(biāo)志,而 isInterrupted() 不改變。

最佳實踐

  • RunnableThreadrun() 方法中,始終通過 while(!isInterrupted())while(running) 循環(huán)執(zhí)行。
  • 如果調(diào)用了可中斷的阻塞方法,一定要處理 InterruptedException,并在異常后重新設(shè)置中斷標(biāo)志或退出。
  • 不要吞掉 InterruptedException(即 catch 后啥也不干),這會導(dǎo)致中斷信號丟失。
  • 在封裝庫或框架時,優(yōu)先使用中斷機制而非自定義標(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)部會調(diào)用 interrupt()

7. 總結(jié)

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

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

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

相關(guān)文章

  • 如何讓W(xué)in10實現(xiàn)Java文件的開機自啟動

    如何讓W(xué)in10實現(xiàn)Java文件的開機自啟動

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

    java LocalDateTime加時間,計算兩個時間的差方式

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

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

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

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

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

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

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

    java中的switch case語句使用詳解

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

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

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

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

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

    ElasticSearch添加索引代碼實例解析

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

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

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

最新評論

宝清县| 东山县| 闻喜县| 长丰县| 贵定县| 湾仔区| 白城市| 甘洛县| 湛江市| 宝丰县| 阿尔山市| 宿迁市| 当涂县| 涿州市| 乐东| 镇远县| 元阳县| 桐乡市| 湟源县| 博爱县| 甘孜| 浦城县| 镇原县| 交城县| 福泉市| 喀喇| 汤阴县| 大石桥市| 南江县| 洛川县| 遵化市| 准格尔旗| 咸宁市| 南部县| 兴仁县| 东明县| 庆安县| 高唐县| 广元市| 衡阳县| 常德市|