通過jstack分析線程死鎖場景

死鎖的四個必要條件:互斥、持有并等待、不可搶占、循環等待。
死鎖場景是兩個線程各自持有某個鎖,并試圖獲取對方持有的鎖,導致互相等待。

創建死鎖示例代碼

package io.renren.controller;import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;/*** 通過jstack分析線程死鎖場景*/
@RestController
public class DeadlockController {// 定義兩個互斥鎖對象private final Object lockA = new Object();private final Object lockB = new Object();@GetMapping("/deadlock")public String triggerDeadlock() {new Thread(() -> {synchronized (lockA) {System.out.println("Thread1 acquired lockA");try { Thread.sleep(100); }catch (InterruptedException e) {}synchronized (lockB) {System.out.println("Thread1 acquired lockB");}}}, "Deadlock-Thread-1").start();new Thread(() -> {synchronized (lockB) {System.out.println("Thread2 acquired lockB");try { Thread.sleep(100); }catch (InterruptedException e) {}synchronized (lockA) {System.out.println("Thread2 acquired lockA");}}}, "Deadlock-Thread-2").start();return "死鎖已觸發,檢查控制臺日志和線程狀態";}}

訪問端點觸發死鎖

http://localhost:8080/deadlock

請添加圖片描述

使用 jstack 分析

查找Java進程PID

jps -l
# 輸出示例:
# 12345 com.example.DeadlockDemoApplication

生成線程轉儲

jstack -l 12345 > thread_dump.txt

請添加圖片描述

分析線程轉儲:
請添加圖片描述
死鎖分析圖解
請添加圖片描述

解決死鎖的方案

方案1:統一鎖獲取順序

// 修改第二個線程的鎖獲取順序
new Thread(() -> {synchronized (lockA) {  // 改為先獲取lockASystem.out.println("Thread2 acquired lockA");try { Thread.sleep(100); } catch (InterruptedException e) {}synchronized (lockB) {System.out.println("Thread2 acquired lockB");}}
}, "Safe-Thread-2").start();

方案2:使用 tryLock 超時機制

//定義成員變量
private final ReentrantLock lock1 = new ReentrantLock();
private final ReentrantLock lock2 = new ReentrantLock();//在函數內部執行
new Thread(() -> {try {if (lock1.tryLock(1, TimeUnit.SECONDS)) {try {System.out.println("Thread1 acquired lock1");Thread.sleep(100);if (lock2.tryLock(1, TimeUnit.SECONDS)) {try {System.out.println("Thread1 acquired lock2");} finally {lock2.unlock();}}} finally {lock1.unlock();}}} catch (InterruptedException e) {e.printStackTrace();}
}).start();

預防死鎖的最佳實踐

鎖順序:統一所有線程的鎖獲取順序

超時機制:使用 tryLock() 替代內置鎖

減少鎖粒度:避免在方法級別使用 synchronized

靜態分析工具:使用 FindBugs/SpotBugs 檢測潛在死鎖

壓力測試:使用 JMeter 模擬高并發場景

最后

實際開發中建議使用 ReentrantLock 等更靈活的工具替代 synchronized,并配合 Arthas 等在線診斷工具進行實時分析。

------------------------------------------------- jstack補充 -----------------------------------------------------
jstack命令用于打印指定Java進程、核心文件或遠程調試服務器的Java線程的Java堆棧跟蹤信息。

jstack命令可以生成JVM當前時刻的線程快照。線程快照是當前JVM內每一條線程正在執行的方法堆棧的集合,生成線程快照的主要目的是定位線程出現長時間停頓的原因,如線程間死鎖、死循環、請求外部資源導致的長時間等待等。

如果java程序崩潰生成core文件,jstack工具可以用來獲得core文件的java stack和native stack的信息,從而可以輕松地知道java程序是如何崩潰和在程序何處發生問題。

當指定的進程在64位Java虛擬機上運行時,可能需要指定-J-d64選項,例如:jstack -J-d64 -m pid。

該命令可能在未來的版本中不可用!!!

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

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

相關文章

PyTorch梯度:深度學習的引擎與實戰解析

一、梯度:深度學習中的指南針 1.1 什么是梯度? 梯度是函數在某一點變化率最大的方向及其大小,就像爬山時最陡峭的上坡方向。在深度學習中,梯度告訴我們如何調整神經網絡參數,使損失函數最小化。 1.2 梯度的重要性 …

【Python爬蟲】詳細入門指南

目錄 一、簡單介紹 二、詳細工作流程以及組成部分 三、 簡單案例實現 一、簡單介紹 在當今數字化信息飛速發展的時代,數據的獲取與分析變得愈發重要,而網絡爬蟲技術作為一種能夠從互聯網海量信息中自動抓取所需數據的有效手段,正逐漸走入…

Golang|Channel 相關用法理解

文章目錄 用 channel 作為并發小容器channel 的遍歷channel 導致的死鎖問題用 channel 傳遞信號用 channel 并行處理文件用channel 限制接口的并發請求量用 channel 限制協程的總數量 用 channel 作為并發小容器 注意這里的 ok 如果為 false,表示此時不僅channel為空…

Windows單機模擬MySQL主從復制

這里寫自定義目錄標題 下載MySQL ZIP壓縮包安裝主庫1、創建配置文件2、安裝服務3、初始化數據庫4、啟動服務5、配置主庫 安裝從庫1、配置ini文件2、安裝服務3、初始化數據庫4、啟動服務5、配置從庫6、驗證從庫狀態 操作主庫驗證 下載MySQL ZIP壓縮包 https://dev.mysql.com/do…

OSPF路由引入

一、基本概念與作用 1.OSPF路由引入指通過自治系統邊界路由器(ASBR)將外部路由(如BGP、RIP、靜態路由或其他OSPF進程的路由)注入當前OSPF域,實現跨協議或跨區域的網絡互通?。 其核心作用包括: ?擴展網…

弱口令爆破

1.簡單介紹 弱口令是指一些簡單易猜的密碼,可通過社工方式和一些爆破工具進行破解,以下介紹一款爆破工具的用法。burpsuite簡稱BP,一款可以利用字典破解賬戶密碼的工具。 2.部署網站 可以使用PHPstudy的Apache服務,也可以使用I…

Vue3+Vite前端項目部署后部分圖片資源無法獲取、動態路徑圖片資源報404錯誤的原因及解決方案

目錄 Vue3vite前端項目部署后部分圖片資源無法獲取、動態路徑圖片資源報404錯誤的原因及解決方案 一、情景介紹 1、問題出現的場景 2、無法加載的圖片寫法 二、反向代理原理簡介 三、造成該現象的原因 四、解決方案 1、放棄動態渲染 2、在頁面掛載的時候引入圖片資源 …

詳解如何從零用 Python復現類似 GPT-4o 的多模態模型

🧠 向所有學習者致敬! “學習不是裝滿一桶水,而是點燃一把火。” —— 葉芝 我的博客主頁: https://lizheng.blog.csdn.net 🌐 歡迎點擊加入AI人工智能社區! 🚀 讓我們一起努力,共創…

榕壹云無人共享系統:基于SpringBoot+MySQL+UniApp的物聯網共享解決方案

無人共享經濟下的技術革新 隨著無人值守經濟模式的快速發展,傳統共享設備面臨管理成本高、效率低下等問題。榕壹云無人共享系統依托SpringBootMySQLUniApp技術棧,結合物聯網與移動互聯網技術,為商家提供低成本、高可用的無人化運營解決方案。…

基于PHP的酒店網上訂房系統(源碼+lw+部署文檔+講解),源碼可白嫖!

摘要 酒店服務是旅游行業的一個重要組成部分,它的作用已經從過去的單一的住宿、結算帳務向全面、高水平的服務型酒店轉變。酒店的服務工作貫穿于整個酒店的市場營銷、預定、入住、退房、結賬等環節,酒店要提高整體工作水平,簡化工作程序&…

【Linux生成SSH秘鑰實現遠程連接】Linux生成SSH秘鑰對與修改服務配置文件實現無密碼遠程連接

文章目錄 前言1. Linux 生成SSH秘鑰對2. 修改SSH服務配置文件3. 客戶端秘鑰文件設置4. 本地SSH私鑰連接測試5. Linux安裝Cpolar工具6. 配置SSHTCP公網地址7. 遠程SSH私鑰連接測試8. 固定SSH公網地址9. 固定SSH地址測試 前言 在數字化江湖中,企業對各種技術的需求就…

# linux 設置寬容模式

linux 設置寬容模式 在Linux系統中,通常沒有直接稱為“寬容模式”的設置選項,但你可以通過幾種方式來模擬或調整系統行為,使其表現得更加“寬容”,特別是在處理錯誤、權限問題或其他潛在問題時。以下是一些常見的方法&#xff1a…

【C++】——lambda表達式

🌟 前言:??C Lambda表達式,當函數開始"叛逆期"?? 你是否有過這樣的崩潰瞬間? 為了寫個??只用到一次??的排序規則,被迫定義了一個類在std::for_each里塞函數指針,代碼瞬間變成"古董級"寫法看著層的循環…

深入解析B站androidApp接口:從bilibili.api.ticket.v1.Ticket/GetTicket到SendMsg的技術分析

前言 最近一段時間,我對B站的App接口進行了深入分析,特別是關注了認證機制和私信功能的實現。通過逆向工程和網絡抓包,發現了B站移動端API的底層工作原理,包括設備標識生成機制、認證流程和消息傳輸協議。本文將分享這些研究成果…

從零開始學A2A一:A2A 協議概述與核心概念

A2A 協議概述與核心概念 學習目標 基礎理解 掌握A2A協議的基本概念和背景理解協議的設計原則和核心思想了解協議在AI領域的重要性 技術掌握 熟悉A2A協議的核心功能組件掌握能力發現和任務管理機制理解多模態交互和安全通信原則 實踐應用 能夠設計基于A2A的智能體系統掌握協議…

2025.04.10-拼多多春招筆試第三題

?? 點擊直達筆試專欄 ??《大廠筆試突圍》 ?? 春秋招筆試突圍在線OJ ?? 筆試突圍OJ 03. 數字重排最大化問題 問題描述 LYA是一位專業的數字設計師。她手中有兩個數字序列 s 1 s_1

蒼穹外賣day04

Spring Task實現定時處理訂單狀態 作用:不需要輸入提示信號,便可定時自動執行程序 使用步驟 1、啟動類上加上注解(EnableScheduling)開啟定時任務調度 2、專門創建一個包來管理執行定時任務的類,該類需要交給IOC容…

BFD:網絡鏈路檢測與聯動配置全攻略

目錄 BFD簡介 BFD會話建立方式和檢測機制 BFD會話建立過程 BFD工作流程 聯動功能 BFD與OSPF聯動配置需求 BFD與OSPF聯動配置實現 BFD與VRRP聯動配置需求 BFD與VRRP聯動配置實現 單臂回聲 BFD默認參數及調整方法 BFD簡介 一種全網統一、檢測迅速、監控網絡中鏈…

【LLM】A2A 與 MCP:剖析 AI Agent 互聯時代的兩種關鍵協議

隨著人工智能技術的飛速發展,AI Agent(智能體)正從理論走向實踐,有望成為提升生產力的關鍵。然而,正如歷史上任何新興技術領域一樣,標準的缺失導致了“筒倉效應”——不同來源、不同框架構建的 Agent 難以有…

免費下載 | 2025清華五道口:“十五五”金融規劃研究白皮書

《2025清華五道口:“十五五”金融規劃研究白皮書》的核心內容主要包括以下幾個方面: 一、五年金融規劃的重要功能與作用 凝聚共識:五年金融規劃是國家金融發展的前瞻性謀劃和戰略性安排,通過廣泛聽取社會各界意見,凝…