Java线程死锁–案例研究

本文将描述从在IBM JVM 1.6上运行的Weblogic 11g生产系统中观察到的最新Java死锁问题的完整根本原因分析。

此案例研究还将证明掌握线程转储分析技能的重要性; 包括用于IBM JVM Thread Dump格式。

环境规格

– Java EE服务器:Oracle Weblogic Server 11g和Spring 2.0.5 –操作系统:AIX 5.3 – Java虚拟机:IBM JRE 1.6.0 –平台类型:门户和订购应用程序
监控和故障排除工具
– JVM线程转储(IBM JVM格式)– Compuware Server Vantage(Weblogic JMX监视和警报)

问题概述

从Compuware Server Vantage观察到并报告了一个严重的线程阻塞问题,该问题影响了我们的2台Weblogic 11g生产托管服务器,从而导致了最终用户的应用程序影响和超时情况。

事实的收集和验证

像往常一样,Java EE问题调查需要收集技术和非技术事实,因此我们可以得出其他事实和/或就根本原因进行结论。 在采取纠正措施之前,要对以下事实进行核实,以便得出根本原因:
·对客户有什么影响? MEDIUM(16个中只有2个受管服务器/ JVM受影响)·受影响平台的最新更改? 是(新的与JMS相关的异步组件)·最近到受影响平台的流量有增加吗? 否·这个问题如何表现出来? 观察到线程突然增加,导致线程快速耗尽。·Weblogic托管服务器重新启动是否解决了问题? 是的,但是几个小时后问题又回来了(不可预测的间歇性模式)

结论1

该问题与间歇性卡住的线程行为有关,该行为当时仅影响少数Weblogic托管服务器

结论2

由于问题是断断续续的,因此不太可能出现全局根本原因,例如下游系统无响应

线程转储分析–第一遍

处理滞留的线程问题时,要做的第一件事是生成JVM线程转储。 无论您的环境规格和问题背景如何,这都是一条黄金法则。 JVM线程转储快照为您提供了有关活动线程及其当时正在执行的处理/任务类型的重要信息。
现在回到我们的案例研究,生成了一个IBM JVM线程转储(javacore.xyz格式),它确实揭示了以下Java线程死锁情况:

1LKDEADLOCK    Deadlock detected !!!NULL           ---------------------NULL           2LKDEADLOCKTHR  Thread '[STUCK] ExecuteThread: '8' for queue: 'weblogic.kernel.Default (self-tuning)'' (0x000000012CC08B00)3LKDEADLOCKWTR    is waiting for:4LKDEADLOCKMON      sys_mon_t:0x0000000126171DF8 infl_mon_t: 0x0000000126171E38:4LKDEADLOCKOBJ      weblogic/jms/frontend/FESession@0x07000000198048C0/0x07000000198048D8: 3LKDEADLOCKOWN    which is owned by:2LKDEADLOCKTHR  Thread '[STUCK] ExecuteThread: '10' for queue: 'weblogic.kernel.Default (self-tuning)'' (0x000000012E560500)3LKDEADLOCKWTR    which is waiting for:4LKDEADLOCKMON      sys_mon_t:0x000000012884CD60 infl_mon_t: 0x000000012884CDA0:4LKDEADLOCKOBJ      weblogic/jms/frontend/FEConnection@0x0700000019822F08/0x0700000019822F20: 3LKDEADLOCKOWN    which is owned by:2LKDEADLOCKTHR  Thread '[STUCK] ExecuteThread: '8' for queue: 'weblogic.kernel.Default (self-tuning)'' (0x000000012CC08B00)

死锁情况可以按照以下方式进行翻译:
– Weblogic线程8正在等待获取Weblogic线程10拥有的对象监视器锁
– Weblogic线程#10正在等待获取Weblogic线程#8拥有的对象监视器锁 结论: Weblogic线程#8和#10都在等待。 永远! 现在,在深入分析根本原因之前,让我为您提供有关Java Thread死锁的高级概述。

Java线程死锁概述

你们中的大多数人可能都熟悉Java Thread死锁原理,但是您真的遇到了真正的死锁问题吗?

根据我的经验,真正的Java死锁很少见,在过去的10年中,我只看到5次此类死锁。 原因是大多数与线程卡住有关的问题是由于线程挂起情况(正在等待远程IO调用等)引起的,而与其他线程没有真正的死锁条件有关。
Java线程死锁是一种情况,例如,线程A等待获取线程B持有的对象监视器锁,而该线程本身正等待获取线程A持有的对象监视器锁。这两个线程将永远彼此等待。 这种情况可以如下图所示:

线程死锁已确认……现在该怎么办?
一旦确认了死锁( 大多数JVM线程转储实现将为您突出显示 ),下一步就是通过检查死锁情况下涉及的每个线程及其当前任务和等待条件,来进行更深入的分析。
在我们的问题案例中,对于涉及死锁条件的每个线程,在部分线程堆栈跟踪下面找到: **请注意,出于保密目的,真实应用程序Java包名称已重命名**

Weblogic线程#8

'[STUCK] ExecuteThread: '8' for queue: 'weblogic.kernel.Default (self-tuning)'' J9VMThread:0x000000012CC08B00, j9thread_t:0x00000001299E5100, java/lang/Thread:0x070000001D72EE00, state:B, prio=1(native thread ID:0x111200F, native priority:0x1, native policy:UNKNOWN)Java callstack:at weblogic/jms/frontend/FEConnection.stop(FEConnection.java:671(Compiled Code))at weblogic/jms/frontend/FEConnection.invoke(FEConnection.java:1685(Compiled Code))at weblogic/messaging/dispatcher/Request.wrappedFiniteStateMachine(Request.java:961(Compiled Code))at weblogic/messaging/dispatcher/DispatcherImpl.syncRequest(DispatcherImpl.java:184(Compiled Code))at weblogic/messaging/dispatcher/DispatcherImpl.dispatchSync(DispatcherImpl.java:212(Compiled Code))at weblogic/jms/dispatcher/DispatcherAdapter.dispatchSync(DispatcherAdapter.java:43(Compiled Code))at weblogic/jms/client/JMSConnection.stop(JMSConnection.java:863(Compiled Code))at weblogic/jms/client/WLConnectionImpl.stop(WLConnectionImpl.java:843)at org/springframework/jms/connection/SingleConnectionFactory.closeConnection(SingleConnectionFactory.java:342)at org/springframework/jms/connection/SingleConnectionFactory.resetConnection (SingleConnectionFactory.java:296)at org/app/JMSReceiver.receive()……………………………………………………………………

Weblogic线程#10

'[STUCK] ExecuteThread: '10' for queue: 'weblogic.kernel.Default (self-tuning)'' J9VMThread:0x000000012E560500, j9thread_t:0x000000012E35BCE0, java/lang/Thread:0x070000001ECA9200, state:B, prio=1(native thread ID:0x4FA027, native priority:0x1, native policy:UNKNOWN)Java callstack:at weblogic/jms/frontend/FEConnection .getPeerVersion(FEConnection.java:1381(Compiled Code))at weblogic/jms/frontend/FESession.setUpBackEndSession(FESession.java:755(Compiled Code))at weblogic/jms/frontend/FESession.consumerCreate(FESession.java:1025(Compiled Code))at weblogic/jms/frontend/FESession.invoke(FESession.java:2995(Compiled Code))at weblogic/messaging/dispatcher/Request.wrappedFiniteStateMachine(Request.java:961(Compiled Code))at weblogic/messaging/dispatcher/DispatcherImpl.syncRequest(DispatcherImpl.java:184(Compiled Code))at weblogic/messaging/dispatcher/DispatcherImpl.dispatchSync(DispatcherImpl.java:212(Compiled Code))at weblogic/jms/dispatcher/DispatcherAdapter.dispatchSync(DispatcherAdapter.java:43(Compiled Code))at weblogic/jms/client/JMSSession.consumerCreate(JMSSession.java:2982(Compiled Code))at weblogic/jms/client/JMSSession.setupConsumer(JMSSession.java:2749(Compiled Code))at weblogic/jms/client/JMSSession.createConsumer(JMSSession.java:2691(Compiled Code))at weblogic/jms/client/JMSSession.createReceiver(JMSSession.java:2596(Compiled Code))at weblogic/jms/client/WLSessionImpl.createReceiver(WLSessionImpl.java:991(Compiled Code))at org/springframework/jms/core/JmsTemplate102.createConsumer(JmsTemplate102.java:204(Compiled Code))at org/springframework/jms/core/JmsTemplate.doReceive(JmsTemplate.java:676(Compiled Code))at org/springframework/jms/core/JmsTemplate$10.doInJms(JmsTemplate.java:652(Compiled Code))at org/springframework/jms/core/JmsTemplate.execute(JmsTemplate.java:412(Compiled Code))at org/springframework/jms/core/JmsTemplate.receiveSelected(JmsTemplate.java:650(Compiled Code))at org/springframework/jms/core/JmsTemplate.receiveSelected(JmsTemplate.java:641(Compiled Code))at org/app/JMSReceiver.receive()……………………………………………………………

如您在上面的“线程跟踪跟踪”中所看到的,这种死锁确实来自我们的应用程序代码,该应用程序代码使用Spring框架API进行JMS使用者实现(在不使用MDB的情况下非常有用)。 堆栈跟踪非常有趣,它揭示了两个线程都在与相同的 Weblogic JMS使用者会话/连接竞争的情况下,并导致死锁情况:
– Weblogic线程#8试图重置关闭当前的JMS连接– Weblogic线程#10试图使用相同的JMS连接/会话以创建新的JMS使用方–触发了线程死锁!

根本原因:非线程安全的Spring JMS SingleConnectionFactory实现

Spring JIRA错误数据库的代码回顾和快速研究确实揭示了以下与上述分析完美相关的以下线程安全缺陷:
#SingleConnectionFactory的resetConnection导致与基础OracleAQ的JMS连接的死锁https://jira.springsource.org/browse/SPR-5987
Spring SingleConnectionFactory的修补程序于2009年发布,确实涉及添加适当的sync {}块,以防止在发生JMS Connection重置操作时线程死锁:

synchronized (connectionMonitor) {//if condition added to avoid possible deadlocks when trying to reset the target connection if (!started) {this.target.start(); started = true; }}

我们的团队目前正计划将该Spring补丁不久后集成到我们的生产环境中。 在我们的测试环境中执行的初始测试是肯定的。

结论

我希望这个案例研究能帮助您理解现实中的Java线程死锁问题,以及适当的线程转储分析技能如何使您能够在代码级快速查明与线程相关的卡住问题的根本原因。 请不要犹豫,发表任何评论或问题。

参考: Java Thread死锁–来自我们的JCG合作伙伴 Pierre-Hugues Charbonneau的案例研究 ,位于Java EE支持模式和Java教程博客上。


翻译自: https://www.javacodegeeks.com/2012/06/java-thread-deadlock-case-study.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/372336.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

bzoj1968: [Ahoi2005]COMMON 约数研究

水题。。。 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,s,t) for(int is;i<t;i) int main(){int ans0,n;scanf("%d",&n);rep(i,1,n) ansn/i;printf("%d\n…

题目1457:非常可乐(广度优先遍历BFS)

题目链接&#xff1a;http://ac.jobdu.com/problem.php?pid1457 详解链接&#xff1a;https://github.com/zpfbuaa/JobduInCPlusPlus 参考代码&#xff1a; // // 1457 非常可乐.cpp // Jobdu // // Created by PengFei_Zheng on 22/04/2017. // Copyright © 2017 Pe…

mysql查询某张表的所有外键_oracle中查询所有外键引用到某张表的记录

欢迎进入Oracle社区论坛&#xff0c;与200万技术人员互动交流 >>进入 oracle中查询所有外键引用到某张表的记录 //查询表的主键约束名 select * from user_constraints e where e.table_name表名;--输入 //查询所有引用到该主键的记录 select b.table_name,b.column_欢迎…

BTrace for Java应用程序简介

本文的目的是学习如何使用BTrace动态跟踪/观察正在运行的Java应用程序&#xff08;JDK 6&#xff09;&#xff0c;而无需更改应用程序的代码和配置参数。 什么是BTrace&#xff1f; BTrace是一个开源项目&#xff0c;始于2007年&#xff0c;最初由A.Sundararajan和K.Balasubra…

丛铭俣 160809324 (作业1)

老师&#xff0c;助教好&#xff01;我是计科3班的丛铭俣&#xff0c;我的性格阳光开朗&#xff0c;待人大方友善&#xff0c;凡事不喜欢斤斤计较&#xff1b;本人热心&#xff0c;喜欢乐于助人&#xff0c;也喜欢和积极向上的人交朋友。最喜欢打羽毛球&#xff0c;其次是篮球&…

mysql死锁分析_MySQL死锁分析

熟悉或者了解数据库的朋友都知道锁的概念&#xff0c;这里不做过多的解析&#xff01;锁的种类有很多&#xff0c;不同数据库的锁管理方式也不同。这里主要谈下MySQL innodb引擎下的死锁。死锁通俗的来讲就是2个事务相互请求对方持有的锁&#xff0c;这样就会造成2个事务相互等…

在Akka中实现主从/网格计算模式

主从模式是容错和并行计算的主要示例。 模式背后的想法是将工作划分为相同的子任务&#xff0c;然后将其委派给从属。 这些从节点或实例将处理工作任务&#xff0c;并将结果发送回主节点。 然后主节点将编译从所有从节点接收到的结果。关键是从节点仅知道如何处理任务&#xff…

java学习笔记总略

二、正文&#xff08;一&#xff09;Java1.接口和抽象类的区别①抽象类里可以有构造方法&#xff0c;而接口内不能有构造方法。②抽象类中可以有普通成员变量&#xff0c;而接口中不能有普通成员变量。③抽象类中可以包含非抽象的普通方法&#xff0c;而接口中所有的方法必须是…

react实现路由跳转_react实现hash路由

众所周知&#xff0c;目前单页面使用的路由有两种实现方式&#xff1a;hash 模式history 模式hash 模式路由原理&#xff1a;我们先来看hash模式&#xff0c;页面首次加载时需要在load事件中解析初始的URL&#xff0c;从而展示进入的页面。当 # 后面的哈希值发生变化时&#xf…

Java中的Google协议缓冲区

总览 协议缓冲区是一种用于结构化数据的开源编码机制。 它是由Google开发的&#xff0c;旨在实现语言/平台中立且可扩展。 在本文中&#xff0c;我的目的是介绍Java平台上下文中协议缓冲区的基本用法。 Protobuff比XML更快&#xff0c;更简单&#xff0c;并且比JSON更紧凑。 当…

匈牙利哦模板 二分匹配 完全匹配问题

匈牙利算法的核心思想就是 腾空间, 有条件 创造,没条件也要创造! bool find(int x){int i,j;for (j1;j<m;j){ //扫描每个被匹配的人 if (line[x][j]true && used[j]false) //如果有关系并且还没有标记过(这里标记的意思是这次查找曾试图改变过的归属问题&a…

ThinkPHP 中验证码的看不清切换

<!--HTML页面--> <!DOCTYPE html><html><head> <title></title></head><body><script type"text/javascript" src"__PUBLIC__/js/jquery-1.8.2.min.js"></script><form action"{:U(H…

mysql从表截取信息_mysql中循环截取用户信息并插入到目标表对应的字段中

操作环境&#xff1a;有表game_list&#xff0c;字段&#xff1a;uid&#xff0c;score1&#xff0c;score2&#xff0c;seat_id&#xff0c;last_update&#xff1b;传入参数为i_player_detail &#xff0c;传入的值为多个用户的id、之前分数、之后分数、座位号&#xff0c;每…

Java中的数组,列表,集合,映射,元组,记录文字

有时&#xff0c;当我对JavaScript的强大功能和表现力感到兴奋时&#xff0c;我发现自己错过了Java世界中的一两个功能。 除了lambda表达式/闭包或任何您想称为“匿名函数”的东西之外&#xff0c;它还对数组&#xff0c;数组&#xff0c;列表&#xff0c;集合&#xff0c;映射…

mysql锁表问题的解决方法_MYSQL锁表问题的解决方法

本文实例讲述了MYSQL锁表问题的解决方法。分享给大家供大家参考&#xff0c;具体如下&#xff1a;很多时候&#xff01;一不小心就锁表&#xff01;这里讲解决锁表终极方法&#xff01;案例一mysql>show processlist;参看sql语句一般少的话mysql>kill thread_id;就可以解…

linux——(1)初识linux

linux有窗口管理员环境和纯文本界面环境&#xff0c;同时linux默认提供6个Terminal来让用户登录。crtlaltF1-6可自由切换。其中如果窗口管理员环境处于运行状态&#xff0c;那么可以按crtlaltF7直接切过去。 常用命令&#xff1a; cd [dir] #进入dir目录下 ls #列出当前目录下的…

4.26学习成果

哇&#xff0c;今天终于开始接触Web了&#xff0c;感觉有点小兴奋&#xff0c;这几天看来那个视频感觉挺有趣的&#xff0c;挺奇妙的。看到人家敲代码&#xff0c;感觉好厉害。但是感觉不懂&#xff0c;所以&#xff0c;要努力学习了。 今天的学习成果&#xff1a; 网页由什么组…

将Glassfish 3连接到外部ActiveMQ 5代理

介绍 在ONVZ&#xff0c;我们将Glassfish 3用作开发和生产应用服务器&#xff0c;我们对其性能和稳定性以及周围的广大社区感到非常满意。 我很少遇到在stackoverflow或java.net上没有匹配解决方案的问题。 作为我们开源策略的一部分&#xff0c;我们还运行了一个定制的ActiveM…

esp8266 lcd 天气_ESP8266 显示实时天气信息

代码文件getdata.h#include #include #include #include #include #include #include #define DEBUG 1#define MAX_CONTENT_SIZE 2000const char* ssid "weather";const char* password "mymymymy";WiFiClient client;HTTPClient http;char response[MAX…

【VS开发】visual studio 2015的NuGet Manager解决方案管理功能

NuGet的官方说明是&#xff1a;NuGet是一款Visual Studio的扩展&#xff0c;它可以简单的安装、升级开源库和工具。 官网地址&#xff1a;http://www.nuget.org/ 官网最醒目的位置就是下载链接&#xff0c;安装完成后我们来快速体验一把。 手上有个小项目需要使用到json格式&am…