Java - 死锁 Dead Lock 定位分析

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: Java - 死锁 Dead Lock 定位分析

20200520144020609.png

Pre

JVM-11虚拟机性能监控与故障处理工具之【JDK的可视化工具-JConsole】


jstack

jstack主要用来查看某个Java进程内的线程堆栈信息 ,建议多杀几次线程dump ,每次都有某个事件,基本没跑了~


用法也很简单


20200520145923952.png


Thread dump

Found one Java-level deadlock:
=============================
"T-ShortConn-4":
  waiting to lock monitor 0x00007f87e1d95718 (object 0x00000006cc86c090, a java.lang.Class),
  which is held by "T-ShortConn-0"
"T-ShortConn-0":
  waiting to lock monitor 0x00007f875c00f188 (object 0x00000006c6f34238, a java.util.concurrent.ConcurrentHashMap),
  which is held by "localhost-startStop-1"
"localhost-startStop-1":
  waiting to lock monitor 0x00007f87e1d95718 (object 0x00000006cc86c090, a java.lang.Class),
  which is held by "T-ShortConn-0"
Java stack information for the threads listed above:
===================================================
"T-ShortConn-4":
  at com.artisan.bus.tool.redis.RedisClusterHelper.getClient(RedisClusterHelper.java:38)
  - waiting to lock <0x00000006cc86c090> (a java.lang.Class for com.artisan.bus.tool.redis.RedisClusterHelper)
  at com.artisan.bus.tool.redis.RedisClusterHelper.listOs(RedisClusterHelper.java:328)
  at com.artisan.bus.tool.redis.RedisClusterHelper.lSize(RedisClusterHelper.java:193)
  at com.artisan.bus.service.comunication.CommunicationService.send(CommunicationService.java:1922)
  at com.artisan.bus.service.comunication.CommunicationService$$FastClassBySpringCGLIB$$cacacc60.invoke(<generated>)
  at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
  at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:721)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
  at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
  at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
  at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
  at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656)
  at com.artisan.bus.service.comunication.CommunicationService$$EnhancerBySpringCGLIB$$8902c097.send(<generated>)
  at net.artisan.manager.DataProcessorManager.send(DataProcessorManager.java:850)
  at net.artisan.manager.DataProcessorManager.processShortLinkData(DataProcessorManager.java:833)
  at net.artisan.common.ShortLinkProcessorThread.run(ShortLinkProcessorThread.java:22)
  at java.lang.Thread.run(Thread.java:748)
"T-ShortConn-0":
  at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:187)
  - waiting to lock <0x00000006c6f34238> (a java.util.concurrent.ConcurrentHashMap)
  at org.springframework.beans.factory.support.AbstractBeanFactory.isTypeMatch(AbstractBeanFactory.java:486)
  at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:432)
  at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:403)
  at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:389)
  at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1002)
  at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:345)
  at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:340)
  at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1093)
  at com.artisan.bus.tool.utils.SpringApplicationContext.getBean(SpringApplicationContext.java:31)
  at com.artisan.bus.tool.redis.RedisClusterHelper.getClient(RedisClusterHelper.java:40)
  - locked <0x00000006cc86c090> (a java.lang.Class for com.artisan.bus.tool.redis.RedisClusterHelper)
  at com.artisan.bus.tool.redis.RedisClusterHelper.listOs(RedisClusterHelper.java:328)
  at com.artisan.bus.tool.redis.RedisClusterHelper.lSize(RedisClusterHelper.java:193)
  at com.artisan.bus.service.comunication.CommunicationService.send(CommunicationService.java:1922)
  at com.artisan.bus.service.comunication.CommunicationService$$FastClassBySpringCGLIB$$cacacc60.invoke(<generated>)
  at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
  at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:721)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
  at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
  at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
  at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
  at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656)
  at com.artisan.bus.service.comunication.CommunicationService$$EnhancerBySpringCGLIB$$8902c097.send(<generated>)
  at net.artisan.manager.DataProcessorManager.send(DataProcessorManager.java:850)
  at net.artisan.manager.DataProcessorManager.processShortLinkData(DataProcessorManager.java:833)
  at net.artisan.common.ShortLinkProcessorThread.run(ShortLinkProcessorThread.java:22)
  at java.lang.Thread.run(Thread.java:748)
"localhost-startStop-1":
  at com.artisan.bus.tool.redis.RedisClusterHelper.getClient(RedisClusterHelper.java:38)
  - waiting to lock <0x00000006cc86c090> (a java.lang.Class for com.artisan.bus.tool.redis.RedisClusterHelper)
  at com.artisan.bus.tool.redis.RedisClusterHelper.del(RedisClusterHelper.java:63)
  at com.artisan.bus.dao.impl.settings.template.strategy.StrategyTemplateDao.cacheStrategyTemplate(StrategyTemplateDao.java:173)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:498)
  at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
  at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
  at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
  at com.sun.proxy.$Proxy82.cacheStrategyTemplate(Unknown Source)
  at com.artisan.bus.service.impl.task.CheckTaskService.cacheStrategyTemplate(CheckTaskService.java:3658)
  at com.artisan.bus.service.impl.task.CheckTaskService$$FastClassBySpringCGLIB$$b794226f.invoke(<generated>)
  at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
  at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:721)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
  at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
  at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
  at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
  at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656)
  at com.artisan.bus.service.impl.task.CheckTaskService$$EnhancerBySpringCGLIB$$7b018424.cacheStrategyTemplate(<generated>)
  at com.artisan.bus.web.filter.ApplicationConfigue.setApplicationContext(ApplicationConfigue.java:74)
  at org.springframework.context.support.ApplicationContextAwareProcessor.invokeAwareInterfaces(ApplicationContextAwareProcessor.java:121)
  at org.springframework.context.support.ApplicationContextAwareProcessor.postProcessBeforeInitialization(ApplicationContextAwareProcessor.java:97)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:409)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1620)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)
  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
  at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
  at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
  - locked <0x00000006c6f34238> (a java.util.concurrent.ConcurrentHashMap)
  at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
  at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
  at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
  at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866)
  at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
  - locked <0x00000006c6f655a8> (a java.lang.Object)
  at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:668)
  at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:634)
  at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:682)
  at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:553)
  at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:494)
  at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:138)
  at javax.servlet.GenericServlet.init(GenericServlet.java:158)
  at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1269)
  - locked <0x00000006c6d54a78> (a org.apache.catalina.core.StandardWrapper)
  at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1182)
  - locked <0x00000006c6d54a78> (a org.apache.catalina.core.StandardWrapper)
  at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1072)
  - locked <0x00000006c6d54a78> (a org.apache.catalina.core.StandardWrapper)
  at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5368)
  at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5660)
  - locked <0x00000006c54f5f78> (a org.apache.catalina.core.StandardContext)
  at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
  - locked <0x00000006c54f5f78> (a org.apache.catalina.core.StandardContext)
  at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:899)
  at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:875)
  at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:652)
  at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1260)
  at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:2002)
  at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
  at java.util.concurrent.FutureTask.run(FutureTask.java:266)
  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
  at java.lang.Thread.run(Thread.java:748)
Found 1 deadlock.


Dead Lock 分析

jstack 杀出来的线程堆栈, 划重点~~~

Found one Java-level deadlock:
=============================
"T-ShortConn-4":
  waiting to lock monitor 0x00007f87e1d95718 (object 0x00000006cc86c090, a java.lang.Class),
  which is held by "T-ShortConn-0"
"T-ShortConn-0":
  waiting to lock monitor 0x00007f875c00f188 (object 0x00000006c6f34238, a java.util.concurrent.ConcurrentHashMap),
  which is held by "localhost-startStop-1"
"localhost-startStop-1":
  waiting to lock monitor 0x00007f87e1d95718 (object 0x00000006cc86c090, a java.lang.Class),
  which is held by "T-ShortConn-0"
Java stack information for the threads listed above:
===================================================


三个线程 T-ShortConn-4 、 T-ShortConn-0 和 localhost-startStop-1


看括号里面的 object xxxxxxx


T-ShortConn-4 想去获取lock 【object 0x00000006cc86c090】 , 但这个lock被 T-ShortConn-0持有

T-ShortConn-0 想去获取lock 【object 0x00000006c6f34238】 , 但这个lock被 localhost-startStop-1持有

localhost-startStop-1 想去获取lock 【object 0x00000006cc86c090】 , 但这个lock被 T-ShortConn-0持有

====》得出结论


T-ShortConn-0 持有的lock 【0x00000006cc86c090】 被 T-ShortConn-4 和 localhost-startStop-1 需要


localhost-startStop-1 持有的lock 【0x00000006c6f34238】 被 T-ShortConn-0 需要


20200520154740389.png


这不就产生deal lock了么?


分析代码

T-ShortConn-0 持有的lock 【0x00000006cc86c090】 那就去dump中查找这个关键字吧

20200520155245743.png

at com.artisan.bus.tool.utils.SpringApplicationContext.getBean(SpringApplicationContext.java:31)
  at com.artisan.bus.tool.redis.RedisClusterHelper.getClient(RedisClusterHelper.java:40)
  - locked <0x00000006cc86c090> (a java.lang.Class for com.artisan.bus.tool.redis.RedisClusterHelper)

localhost-startStop-1 持有的lock 【0x00000006c6f34238】


20200520155426184.png


DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:187) 返回的是一个 ConcurrentHashMap , lock类型就是 ConcurrentHashMap。

at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
  - locked <0x00000006c6f34238> (a java.util.concurrent.ConcurrentHashMap)


解决


解决方法: 提前初始化RedisClusterHelper这个单例

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
1月前
|
存储 Java
【编程基础知识】 分析学生成绩:用Java二维数组存储与输出
本文介绍如何使用Java二维数组存储和处理多个学生的各科成绩,包括成绩的输入、存储及格式化输出,适合初学者实践Java基础知识。
75 1
|
2月前
|
缓存 JavaScript Java
常见java OOM异常分析排查思路分析
Java虚拟机(JVM)遇到内存不足时会抛出OutOfMemoryError(OOM)异常。常见OOM情况包括:1) **Java堆空间不足**:大量对象未被及时回收或内存泄漏;2) **线程栈空间不足**:递归过深或大量线程创建;3) **方法区溢出**:类信息过多,如CGLib代理类生成过多;4) **本机内存不足**:JNI调用消耗大量内存;5) **GC造成的内存不足**:频繁GC但效果不佳。解决方法包括调整JVM参数(如-Xmx、-Xss)、优化代码及使用高效垃圾回收器。
146 15
常见java OOM异常分析排查思路分析
|
21天前
|
Java 开发者
在Java多线程编程的世界里,Lock接口正逐渐成为高手们的首选,取代了传统的synchronized关键字
在Java多线程编程的世界里,Lock接口正逐渐成为高手们的首选,取代了传统的synchronized关键字
44 4
|
25天前
|
存储 Java 关系型数据库
在Java开发中,数据库连接是应用与数据交互的关键环节。本文通过案例分析,深入探讨Java连接池的原理与最佳实践
在Java开发中,数据库连接是应用与数据交互的关键环节。本文通过案例分析,深入探讨Java连接池的原理与最佳实践,包括连接创建、分配、复用和释放等操作,并通过电商应用实例展示了如何选择合适的连接池库(如HikariCP)和配置参数,实现高效、稳定的数据库连接管理。
47 2
|
26天前
|
Java 关系型数据库 数据库
面向对象设计原则在Java中的实现与案例分析
【10月更文挑战第25天】本文通过Java语言的具体实现和案例分析,详细介绍了面向对象设计的五大核心原则:单一职责原则、开闭原则、里氏替换原则、接口隔离原则和依赖倒置原则。这些原则帮助开发者构建更加灵活、可维护和可扩展的系统,不仅适用于Java,也适用于其他面向对象编程语言。
15 2
|
1月前
|
Java
让星星⭐月亮告诉你,Java synchronized(*.class) synchronized 方法 synchronized(this)分析
本文通过Java代码示例,介绍了`synchronized`关键字在类和实例方法上的使用。总结了三种情况:1) 类级别的锁,多个实例对象在同一时刻只能有一个获取锁;2) 实例方法级别的锁,多个实例对象可以同时执行;3) 同一实例对象的多个线程,同一时刻只能有一个线程执行同步方法。
19 1
|
1月前
|
小程序 Oracle Java
JVM知识体系学习一:JVM了解基础、java编译后class文件的类结构详解,class分析工具 javap 和 jclasslib 的使用
这篇文章是关于JVM基础知识的介绍,包括JVM的跨平台和跨语言特性、Class文件格式的详细解析,以及如何使用javap和jclasslib工具来分析Class文件。
48 0
JVM知识体系学习一:JVM了解基础、java编译后class文件的类结构详解,class分析工具 javap 和 jclasslib 的使用
|
1月前
|
Java
Java面试题之cpu占用率100%,进行定位和解决
这篇文章介绍了如何定位和解决Java服务中CPU占用率过高的问题,包括使用top命令找到高CPU占用的进程和线程,以及使用jstack工具获取堆栈信息来确定问题代码位置的步骤。
110 0
Java面试题之cpu占用率100%,进行定位和解决
|
1月前
|
Java 开发者
在 Java 多线程编程中,Lock 接口正逐渐取代传统的 `synchronized` 关键字,成为高手们的首选
【10月更文挑战第6天】在 Java 多线程编程中,Lock 接口正逐渐取代传统的 `synchronized` 关键字,成为高手们的首选。相比 `synchronized`,Lock 提供了更灵活强大的线程同步机制,包括可中断等待、超时等待、重入锁及读写锁等高级特性,极大提升了多线程应用的性能和可靠性。通过示例对比,可以看出 Lock 接口通过 `lock()` 和 `unlock()` 明确管理锁的获取和释放,避免死锁风险,并支持公平锁选择和条件变量,使其在高并发场景下更具优势。掌握 Lock 接口将助力开发者构建更高效、可靠的多线程应用。
25 2
|
1月前
|
Java
如何从Java字节码角度分析问题|8月更文挑战
如何从Java字节码角度分析问题|8月更文挑战
下一篇
无影云桌面