Apache Ignite 生產級的線程池關閉工具方法揭秘

Apache Ignite 中用于 安全、可靠地關閉線程池(ExecutorService 的關鍵邏輯。我們來一步步深入理解它的設計思想和實現細節。


🧱 一、核心方法:U.shutdownNow(...)

public static void shutdownNow(Class<?> owner, @Nullable ExecutorService exec, @Nullable IgniteLogger log
)

? 功能:

安全地關閉一個 ExecutorService,并等待它完全停止。

🔍 參數說明:

參數含義
owner誰創建了這個線程池(用于日志記錄)
exec要關閉的線程池(可能為 null
log日志組件(可能為 null

🚀 方法執行流程

1. 判空保護
if (exec != null) { ... }
  • 如果線程池是 null,直接跳過 —— 避免空指針異常

2. 立即關閉:shutdownNow()
List<Runnable> tasks = exec.shutdownNow();
  • shutdownNow() 會:
    • 嘗試 中斷所有正在運行的工作線程
    • 返回 尚未執行的任務列表(隊列中的任務)

?? 注意:它不保證正在運行的任務會被中斷成功(比如任務中捕獲了 InterruptedException 或未響應中斷)


3. 檢查是否有“幸存任務”
if (!F.isEmpty(tasks))U.warn(log, "Runnable tasks outlived thread pool executor service [...]");
  • F.isEmpty(...) 是 Ignite 的工具方法,判斷集合是否為空
  • 如果返回的任務非空 → 說明有些任務還沒來得及執行就被“拋棄”了
  • 打印警告日志,包含:
    • 線程池所有者(owner
    • 未執行的任務列表(幫助排查問題)

📌 這是非常重要的 可觀測性設計:告訴你“哪些任務丟了”


4. 等待線程池終止
try {exec.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
}
catch (InterruptedException ignored) {warn(log, "Got interrupted while waiting for executor service to stop.");exec.shutdownNow(); // 再次嘗試Thread.currentThread().interrupt(); // 恢復中斷標志
}
🔹 awaitTermination(...) 的作用:
  • 阻塞當前線程,直到線程池真正終止
  • 使用 Long.MAX_VALUE 表示“無限等待” → 確保一定等到為止
🔹 為什么捕獲 InterruptedException
  • 在等待過程中,當前線程可能被其他線程中斷
  • 我們不能“吞掉”這個中斷信號(否則上層邏輯可能無法感知中斷)
  • 所以:
    1. 打個日志
    2. 再調一次 shutdownNow()(加強關閉力度)
    3. 恢復中斷狀態Thread.currentThread().interrupt()

? 這是 Java 多線程編程中的 最佳實踐:不丟失中斷信號


🔄 二、封裝調用:stopExecutors(...)stopExecutors0(...)

private void stopExecutors(IgniteLogger log) {boolean interrupted = Thread.interrupted();try {stopExecutors0(log);}finally {if (interrupted)Thread.currentThread().interrupt();}
}

? 為什么要兩層?

這是為了 正確處理線程中斷狀態

🔍 詳細解釋:

Thread.interrupted()
  • 是一個靜態方法
  • 返回當前線程是否被中斷,并清除中斷標志

所以:

boolean interrupted = Thread.interrupted();

→ 拿到中斷狀態后,中斷標志就被清除了。

finally 塊中:
if (interrupted)Thread.currentThread().interrupt();

→ 如果之前是中斷的,就重新設置中斷標志

? 目的:不改變外部線程的中斷狀態,即“來的時候什么樣,走的時候還什么樣”


stopExecutors0(...):真正干活的方法
private void stopExecutors0(IgniteLogger log) {assert log != null;U.shutdownNow(getClass(), snpExecSvc, log);// 可能還有其他線程池...
}
  • 斷言日志不為空
  • 調用 U.shutdownNow 關閉 snpExecSvc(可能是 striped executor 或其他線程池)
  • 可能還會關閉其他線程池(如 IO、查詢、系統任務等)

🎯 三、整體作用總結

目標實現方式
安全關閉線程池shutdownNow() + awaitTermination()
防止任務丟失檢查 shutdownNow() 返回的任務,打警告日志
避免中斷信號丟失保存并恢復中斷狀態
增強可觀測性記錄線程池所有者、未執行任務
健壯性空值保護、異常處理、重復嘗試

🧩 四、類比理解

想象你在關閉一家快遞分揀中心:

  1. 廣播通知:“所有人立刻停止工作!” → shutdownNow()
  2. 清點包裹:看看還有多少包裹沒來得及處理 → List<Runnable> tasks
  3. 上報丟失件:如果有未處理的包裹,上報給管理層 → 打日志
  4. 等員工全部離崗:你在門口等著,直到最后一個員工離開 → awaitTermination
  5. 遇到警察攔路(中斷):你被打斷等待,但你記得自己還沒關完門 → 恢復中斷標志

? 五、最佳實踐提煉(可用于你自己的項目)

public static void safeShutdown(ExecutorService exec, String name, Logger log) {if (exec == null) return;// 1. 嘗試立即關閉List<Runnable> remainingTasks = exec.shutdownNow();// 2. 報告未執行任務if (!remainingTasks.isEmpty()) {log.warn("Tasks lost during shutdown of {}: {}", name, remainingTasks.size());}// 3. 等待終止try {if (!exec.awaitTermination(30, TimeUnit.SECONDS)) {log.warn("Executor {} didn't terminate in time, forcing...");exec.shutdownNow(); // 再試一次}} catch (InterruptedException e) {log.warn("Shutdown interrupted, forcing shutdown.");exec.shutdownNow();Thread.currentThread().interrupt(); // 恢復中斷}
}

💡 你可以根據需要調整超時時間(比如不用 Long.MAX_VALUE


📌 六、一句話總結

U.shutdownNow(...) 是一個 生產級的線程池關閉工具方法,它不僅嘗試關閉線程池,還關注 任務是否丟失、線程是否真正退出、中斷信號是否保留,體現了 Ignite 對 穩定性、可觀測性和健壯性 的高度重視。


如果你在開發中間件、框架或高可用系統,這種關閉模式 必須掌握并復用

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/92852.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/92852.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/92852.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Unity:GUI筆記(一)——文本、按鈕、多選框和單選框、輸入框和拖動條、圖片繪制和框繪制

寫在前面&#xff1a;寫本系列(自用)的目的是回顧已經學過的知識、記錄新學習的知識或是記錄心得理解&#xff0c;方便自己以后快速復習&#xff0c;減少遺忘。主要是唐老師的課程。一、重要參數、文本、按鈕GUI相關代碼需要寫在private void OnGUI()中。該函數每幀執行&#x…

wordpress從wp_nav_menu中獲取菜單項

從wp_nav_menu中獲取菜單項&#xff0c;然后檢查這些菜單項是否對應分類(Category)&#xff0c;并輸出這些分類的ID。 以下是完整的代碼實現&#xff1a; <?php // 獲取指定菜單位置的菜單項 $menu_items wp_get_nav_menu_items(wodepress); // wodepress 是菜單位置的名…

第4章 程序段的反復執行2 while語句P128練習題(題及答案)

&#xff08;&#xff08;1&#xff09;閱讀程序#include <bits/stdc.h> using namespace std; //湯永紅 int main(){int n,s0;cin >> n;while(n){s s * 10 n % 10;n / 10;}cout << s << endl;return 0; }分別輸入&#xff1a;0 1024 1234567890輸出…

圖解軟件系統組成

這是基于 ??PlantUML?? 繪制的軟件系統組成部分思維導圖&#xff0c;聚焦技術路線與文件類型的對應關系&#xff0c;采用分層架構展示核心模塊&#xff1a;startmindmap * **軟件系統組成部分*** **一、核心技術棧*** 后端技術* 技術路線: Python Web 框架* 文件類型: .py …

【傳奇開心果系列】Flet框架實現的多人訪問web數據表高并發前后端自定義框架模板

Flet框架實現的多人訪問web數據表高并發前后端自定義框架模板一、效果展示截圖二、應用場景介紹1. **多用戶實時協作**2. **產品管理**3. **數據可視化**三、特色說明1. **實時通信**2. **高性能**3. **用戶友好的界面**4. **日志記錄**5. **安全性**四、總結五、源碼下載地址六…

農業智慧大屏系統 - Flask + Vue實現

下面我將實現一個完整的農業智慧大屏系統&#xff0c;使用Flask作為后端框架&#xff0c;前端使用Vue.js結合ECharts進行數據可視化展示。 設計思路 前端部分&#xff1a; 使用Vue.js構建響應式界面 使用ECharts實現各類農業數據可視化 使用CSS Grid布局實現大屏適配 后端…

Linux中Https配置與私有CA部署指南

Linux中Https配置與私有CA部署指南 一、HTTPS 核心概念特性HTTPHTTPS協議明文傳輸HTTP SSL/TLS端口80443加密未加密數據加密二、SSL/TLS 握手流程 Client → Server ClientHello&#xff1a;支持哪些版本、支持哪些加密算法&#xff0c;隨機生成一組32字節數據 random_c Serve…

【軟考架構】主流數據持久化技術框架

JDO與JPA JDO&#xff08;Java Data Objects&#xff09;和JPA&#xff08;Java Persistence API&#xff09;都是Java中用于對象持久化的規范&#xff0c;但它們在設計目標、技術背景和應用場景上存在顯著區別。以下是兩者的核心對比&#xff1a;1. 規范背景與維護方 JDO&…

服務日志、監控

服務怎么做監控和告警使用 Prometheus 和 Grafana 來實現整個微服務集群的監控和告警&#xff1a;Prometheus&#xff1a;Prometheus 是一個開源的監控系統&#xff0c;具有靈活的數據模型和強大的查詢語言&#xff0c;能夠收集和存儲時間序列數據。它可以通過 HTTP 協議定期拉…

秋招筆記-8.12

我決定從今天開始&#xff0c;在每天的學習內容中加入算法的內容&#xff0c;大致分布時間的話&#xff0c;假設我一天可以學習八個小時&#xff0c;那算法兩個小時&#xff0c;八股三個小時&#xff0c;項目三個小時這樣的分布差不多吧。之所以還是需要做做筆試一是為了應對面…

【從0帶做】基于Springboot3+Vue3的校園表白墻系統

大家好&#xff0c;我是武哥&#xff0c;最近給大家手擼了一個基于SpringBoot3Vue3的校園表白墻系統&#xff0c;可用于畢業設計、課程設計、練手學習&#xff0c;系統全部原創&#xff0c;如有遇到網上抄襲站長的&#xff0c;歡迎聯系博主~ 資料獲取方式 請點開作者頭像看下…

【Linux系列】服務器 IP 地址查詢

博客目錄一、hostname 命令&#xff1a;簡單高效的 IP 查詢工具命令詳解實際應用技巧注意事項二、ip 命令&#xff1a;新一代網絡配置全能工具基本用法在服務器管理和網絡運維中&#xff0c;快速準確地獲取服務器的 IP 地址是一項基本但至關重要的技能。無論是進行遠程連接、配…

【完美解決】在 Ubuntu 24.04 上為小米 CyberDog 2 刷機/交叉編譯:終極 Docker 環境搭建指南

摘要 本文旨在為廣大開發者提供一份在非官方推薦的 Ubuntu 24.04 系統上&#xff0c;成功為小米機器狗 CyberDog 2 進行刷機和交叉編譯的終極解決方案。通過層層排查 setup.sh 依賴缺失、No devices to flash 以及交叉編譯 Segmentation fault 等疑難雜癥&#xff0c;我們發現根…

XX生產線MES系統具體實施方案

一、系統架構設計1. 整體架構圖2. 技術組件清單模塊技術選型部署要求應用服務Spring Boot 3.2 Spring CloudKubernetes Pod (4C8G)實時通信Kafka 3.6 WebSocket3節點集群工業協議Eclipse Milo (OPC UA)獨立服務器 (2C4G)數據庫PostgreSQL 15 TimescaleDB 2.10SSD存儲, 主從復…

Go語言實戰案例:使用模板渲染HTML頁面

在 Web 開發中&#xff0c;身份驗證是一個繞不開的話題。傳統的 Session 機制依賴服務器存儲用戶狀態&#xff0c;而在微服務、分布式架構下&#xff0c;這種方式可能會導致狀態同步困難。 JWT&#xff08;JSON Web Token&#xff09;是一種無狀態的、跨平臺的身份驗證解決方案…

@RequestMapping接收文件格式的形參(方法參數)

需求&#xff1a;將文件上傳到OSS&#xff0c;忽略域名與路徑&#xff0c;將文件名以 “img1.png,img2.png,img3.png”保存到數據庫中 1、先看結果 后端要接收postman傳遞的file文件2、SpringBoot接收參數方式 很顯然&#xff0c;上面postman上傳的地方可以傳入多個文件&#x…

【數據分享】2020-2022年我國鄉鎮的逐日最高氣溫數據(Shp/Excel格式)

之前我們分享過2020—2022年中國0.01分辨率逐日最高氣溫柵格數據&#xff08;可以查看之前的文章獲悉詳情&#xff09;&#xff01;該數據是研究者張凌, 胡英屹等發布在國家冰川凍土沙漠科學數據中心平臺上的高分辨最高氣溫數據。很多小伙伴拿到數據后反饋柵格數據不太方便使用…

為什么C++主函數 main 要寫成 int 返回值 | main(int argc, char* argv[]) 這種寫法是什么意思?

主函數 main 要寫成 int 返回值&#xff1f;main(int argc, char* argv[]) 為什么里面沒有 cin 也能讀到數據&#xff0c;數據是怎么傳進去的&#xff1f;本文將一步步回答這些問題。1. 為什么 main 要寫成 intC 標準&#xff08;ISO/IEC 14882&#xff09;規定&#xff0c;mai…

【oracle閃回查詢】記錄字段短時間被修改的記錄

SELECT versions_starttime, versions_endtime, versions_operation, versions_xid, [字段1], [字段2] – 替換為實際字段名 FROM 表名 VERSIONS BETWEEN TIMESTAMP SYSTIMESTAMP - INTERVAL ‘15’ MINUTE AND SYSTIMESTAMP --15分鐘內 WHERE id ‘目標ID’ – 指定記錄的唯…

【軟考中級網絡工程師】知識點之 IP 組播技術:從原理到實戰

目錄一、IP 組播技術概述1.1 什么是 IP 組播1.2 IP 組播與其他傳輸方式對比二、IP 組播地址詳解2.1 IPv4 組播地址范圍及分類2.2 特殊 IPv4 組播地址示例2.3 IPv6 組播地址結構與特點2.4 IP 組播地址與 MAC 地址的映射關系三、IP 組播協議剖析3.1 IGMP 協議深度解析3.2 PIM 協議…