我开发的worker,每隔几个月线上都会阻塞一次,一直都没查出问题。今天终于了了这个心结。把解决过程总结下和大家分享。

首先用jstack命令打出这个进程的全部线程堆栈。拿到线程dump文件之后,搜索自己的worker名字。

"DefaultQuartzScheduler_Worker-10" prio=10 tid=0x00007f55cd54d800 nid=0x3e2e waiting for monitor entry [0x00007f51ab8f7000]

java.lang.Thread.State: BLOCKED (on object monitor)

at com.jd.chat.worker.service.impl.NewPopAccountSyncServiceImpl.addAccounts(NewPopAccountSyncServiceImpl.java:86)

- waiting to lock <0x0000000782359268> (a com.jd.chat.worker.service.impl.NewPopAccountSyncServiceImpl)

at com.jd.chat.worker.service.timer.AccountIncSyncTimer.run(AccountIncSyncTimer.java:114)

at com.jd.chat.worker.service.timer.AbstractTimer.start(AbstractTimer.java:44)

at com.jd.chat.worker.service.timer.AbstractTimer.doJob(AbstractTimer.java:49)

at com.jd.chat.worker.web.context.StartAppListener$TimerJob.execute(StartAppListener.java:188)

at org.quartz.core.JobRunShell.run(JobRunShell.java:202)

at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)

- locked <0x0000000783641c68> (a java.lang.Object)

很快便找到了线程在哪一行被阻塞。但是酒瓶这么点信息,并不能查出问题的真正原因,这里推荐一个工具,叫tda.bat。同事给我的,网上应该有下载。把这个dump文件导入到tda中。找到阻塞的线程。阻塞的线程是红色的。

之所以说这个软件好,是因为当你找到blocked的线程后,界面的下方,会打出阻塞的更详细的线程堆栈。截取这个堆栈的部分信息。

at org.mariadb.jdbc.MySQLPreparedStatement.execute(MySQLPreparedStatement.java:141)

at org.apache.commons.dbcp.DelegatingPreparedStatement.execute(DelegatingPreparedStatement.java:172)

at org.apache.commons.dbcp.DelegatingPreparedStatement.execute(DelegatingPreparedStatement.java:172)

at com.ibatis.sqlmap.engine.execution.SqlExecutor.executeUpdate(SqlExecutor.java:80)

at com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.sqlExecuteUpdate(MappedStatement.java:216)

at com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeUpdate(MappedStatement.java:94)

at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.update(SqlMapExecutorDelegate.java:457)

at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.update(SqlMapSessionImpl.java:90)

at org.springframework.orm.ibatis.SqlMapClientTemplate$9.doInSqlMapClient(SqlMapClientTemplate.java:380)

at org.springframework.orm.ibatis.SqlMapClientTemplate$9.doInSqlMapClient(SqlMapClientTemplate.java:1)

at org.springframework.orm.ibatis.SqlMapClientTemplate.execute(SqlMapClientTemplate.java:200)

at org.springframework.orm.ibatis.SqlMapClientTemplate.update(SqlMapClientTemplate.java:378)

at com.jd.im.data.dataresource.ImSqlMapClientTemplate.retriedWithoutAnyInterventionUpdate(ImSqlMapClientTemplate.java:169)

at com.jd.im.data.dataresource.ImSqlMapClientTemplate.update(ImSqlMapClientTemplate.java:137)

at com.jd.chat.dao.impl.WriteDaoImpl.update(WriteDaoImpl.java:21)

at com.jd.chat.zone.service.impl.GroupServiceImpl.updateRoute(GroupServiceImpl.java:766)

at com.jd.chat.worker.service.impl.NewPopAccountSyncServiceImpl.addAccounts(NewPopAccountSyncServiceImpl.java:267)

- locked <0x0000000782359268> (a com.jd.chat.worker.service.impl.NewPopAccountSyncServiceImpl)

这个才是真正有用的堆栈!它告诉了我程序是在执行SQL的时候,SQL发生死锁,于是线程被阻塞。它还提供了更有用的信息,那就是到底是哪个SQL导致的死锁。堆栈的倒数第三行指示了导致死锁的SQL。

但是一定要用这个工具才能找到具体的原因吗?答案当然是NO!

告诉大家怎么不通过工具找到阻塞的真正原因!

刚刚通过“BLOCKED”关键字搜到了线程堆栈,找到它的线程名“DefaultQuartzScheduler_Worker-10”。OK,然后,把最后的10改成1,也就是“DefaultQuartzScheduler_Worker-1”,然后再拿这个关键字搜索整个进程堆栈。

"DefaultQuartzScheduler_Worker-1" prio=10 tid=0x00007f55cd2aa000 nid=0x3e25 runnable [0x00007f51b02c0000]

java.lang.Thread.State: RUNNABLE

at java.net.SocketInputStream.socketRead0(Native Method)

at java.net.SocketInputStream.read(SocketInputStream.java:129)

at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)

at java.io.BufferedInputStream.read1(BufferedInputStream.java:258)

at java.io.BufferedInputStream.read(BufferedInputStream.java:317)

- locked <0x0000000791370d50> (a java.io.BufferedInputStream)

at org.mariadb.jdbc.internal.common.packet.buffer.ReadUtil.readFully(ReadUtil.java:82)

at org.mariadb.jdbc.internal.common.packet.buffer.ReadUtil.readFully(ReadUtil.java:92)

at org.mariadb.jdbc.internal.common.packet.RawPacket.nextPacket(RawPacket.java:77)

at org.mariadb.jdbc.internal.common.packet.SyncPacketFetcher.getRawPacket(SyncPacketFetcher.java:67)

at org.mariadb.jdbc.internal.mysql.MySQLProtocol.getResult(MySQLProtocol.java:891)

at org.mariadb.jdbc.internal.mysql.MySQLProtocol.executeQuery(MySQLProtocol.java:982)

at org.mariadb.jdbc.MySQLStatement.execute(MySQLStatement.java:280)

- locked <0x0000000791370678> (a org.mariadb.jdbc.internal.mysql.MySQLProtocol)

at org.mariadb.jdbc.MySQLPreparedStatement.execute(MySQLPreparedStatement.java:141)

贴出这个进程堆栈的一部分。这个进程堆栈其实也就是刚刚tda软件界面下方展示的导致线程阻塞的真正的堆栈!这个线程是runnable状态的,可惜mysql是锁死的。也就是说阻塞在了mysql里。

版权声明:本文为博主原创文章,未经博主允许不得转载。

原文:http://blog.csdn.net/bruce128/article/details/47402669

查看java线程堵塞排查_java线程阻塞问题排查相关推荐

  1. java查询线程状态命令_JAVA 线程死锁,以及linux 命令和jstack 命令 查看线程死锁状态信息...

    /* * Copyright (C) 2009 The doctor Authors * https://github.com/doctorwho1986 * * Licensed under the ...

  2. java 同步转并行_Java线程与并行编程(二)

    你好,我是goldsunC 让我们一起进步吧! 线程的控制与同步 线程的状态与生命周期 '每个Java程序都有一个默认的主线程,想要实现多线程,必须在主线程中创建新的线程对象.新建的线程在它的一个完整 ...

  3. java线程不执行_java线程池,阿里为什么不允许使用Executors?

    带着问题 阿里Java代码规范为什么不允许使用Executors快速创建线程池? 下面的代码输出是什么? ThreadPoolExecutor executor = new ThreadPoolExe ...

  4. java方法生命周期_Java线程的第二种实现方式以及生命周期

    上篇中我们了解了Java线程的第一种实现方式,主要分两步,第一步是继承java.lang.Thread; 第二步是重写run()方法.接下来我们来看Java线程的第二种实现方式,也是分为两步,第一步, ...

  5. java 线程 状态 图_Java线程中的生命周期和状态控制图文详解

    这篇文章主要介绍了Java线程的生命周期和状态控制,需要的朋友可以参考下 一.线程的生命周期 线程状态转换图: 1.新建状态 用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处于 ...

  6. java线程详解_Java线程详解

    程序.进程.线程的概念程序(program):是为完成特定任务.用某种语言编写的一组指令的集合.即指一段静态的代码,静态对象. 进程(process):是程序的一次执行过程,或是正在运行的一个程序.动 ...

  7. java 线程池数量_java线程池及创建多少线程合适

    java线程池 1.以下是ThreadPoolExecutor参数完备构造方法: public ThreadPoolExecutor(int corePoolSize,int maximumPoolS ...

  8. 如何查看JAVA某个进程下的线程

    微信搜索:"二十同学" 公众号,欢迎关注一条不一样的成长之路 jps -lvm jps -lvm 用于查看当前机器上运行的java进程. 可以看到所有运行的java进程都列出来了 ...

  9. java线程池功能_Java线程池总结

    一.线程池 线程池适合处理的任务:执行时间短.工作内容较为单一. 合理使用线程池带来的好处: 1)降低资源消耗:重复利用已创建的线程降低线程创建和销毁造成的开销 2)提高响应速度:当任务到达时,任务可 ...

最新文章

  1. Dijkstra算法--有向图的源点到其他顶点的最短路径(连接矩阵、邻接矩阵两种方式)
  2. 人民币升值与美元贬值
  3. 取MySQL最后几行数据
  4. Facebook宕机背后,我们该如何及时发现DNS问题
  5. 图的四种最短路径算法
  6. 如何用css和HTML结合画熊,结合伪元素实现的纯CSS3高级图形绘制
  7. PHP与MYSQL数据库链接方法
  8. ASP.NET Core 新建项目(Windows) - ASP.NET Core 基础教程 - 简单教程,简单编程
  9. 常见十四种的Java算法
  10. html在线编辑器 哪个好用,可视化HTML富文本编辑器有哪些?哪个好用?
  11. 关于使用ArcGIS裁剪栅格后像元值发生变化的问题
  12. ESP32 micropython 应用填坑(一):蓝牙
  13. ARM9——五级流水线结构,以及PC指针
  14. 监控摄像头角度范围计算方法
  15. ios CAF音频转换为MP3
  16. 【软件推荐】使用手机和平板作电脑副屏扩展
  17. 中国象棋残局库构建[抄]
  18. NLP基本功-文本相似度 | AI产品经理需要了解的AI技术通识
  19. Laravel 中管道设计模式的使用 —— 中间件实现原理探究
  20. “'react-scripts' 不是内部或外部命令,也不是可运行的程序或批处理文件。”解决方法

热门文章

  1. 学生成绩管理分析系统
  2. 安卓app开发方案_新闻App开发方案
  3. Python语言的数据类型及表示方法
  4. 学习笔记(25):第一章: 路由与模板-Web前端技术与框架 5
  5. 积加(跨境ERP)与金蝶云星空单据集成对接
  6. Python模拟栈(stack)进出--实现栈的先进后出
  7. 2009年中国交直流电机行业市场分析及投资咨询报告
  8. 求知欲 心有所想,心有所选
  9. eclipse环境下报错:log cannot be resolved
  10. 为何全视觉方案无法实现真正的自动驾驶