java线程阻塞问题排查

    我开发的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中。找到阻塞的线程。阻塞的线程是红色的。

java线程阻塞问题排查

   之所以说这个软件好,是因为当你找到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里。


更多相关文章
  • 6.适配器模式(Adapter)  适配器模式将某个类的接口转换成客户端期望的另一个接口表示,目的是消除由于接口不匹配所造成的类的兼容性问题.主要分为三类:类的适配器模式.对象的适配器模式.接口的适配器模式.首先,我们来看看类的适配器模式,先看类图: 核心思想就是:有一个Source类,拥有一个方法 ...
  • 专车平台是好东西,但上面挂靠的私家车太多,出租车自然竞争不过.出租车公司有17%的租赁税.20%企业所得税,你们公司交了没有?- 广骏出租车公司副总经理李超恒既然现场70%的观众都坐过专车,如果说这么多人都在做违法的事情,这里面就很值得深思,法规到底是用来干吗的?- 我有车公司市场部总监温雅贤出租车 ...
  • 图中为网秦CEO林宇易网科技讯 美国时间5月5日消息,国内移动互联网安全企业网秦今日在纽约交易所上市交易.开市钟敲响之前,网秦高管齐聚纽交所一楼交易大厅,讨论即将到来的开盘价格."应该在20美元左右."多名高管相互讨论.而开盘11.5美元的价格,开盘两分钟后随即破发,这让身在交易 ...
  • 通常情况下, 当我们试图访问某个不存在的或者没有赋值的变量时,就会得到一个undefined值.Javascript会自动将声明是没有进行初始化的变量设为undifined. 如果一个变量根本不存在会发生什么事: >>> foo ReferenceError: foo is not ...
  • Seek the Name, Seek the Fame Time Limit: 2MS   Memory Limit: 65536K Total Submissions: 14188   Accepted: 7068 Description The little cat is so famous, ...
  • 前 言 对于大多数的网络服务器,最广泛的功能就是开通HTTP服务,达到开放和发布网站的目的.目前绝大多数的网络交互程序,例如论坛.社区等等也是基于HTTP而建立的. 在这里,我们通过Web服务器软件中使用量超过半数的自由软件Apache,来构建一台能够满足实际要求的多功能Web服务器,使它能够在我们 ...
一周排行
  • Technorati 标记: Field,Method,Constructor,java 承接前篇对java Reflection的介绍 : Class对象的获取 , 详细讲解了四种获取Class对象的方法: 获取c ...
  • 2011年10月27日,亚马逊全球运营高级副总裁马克·奥纳托(Marc Onetto)和中国区总裁王汉华,在昆山联合宣布卓越亚马逊改名为亚马逊中国,启用短域名z.cn,并同时宣布亚马逊中国最大的运营中心--昆山运营中 ...
  • 时间:0 今天在开发的时候发现了一个iOS8的定位问题,执行操作之后,不会调用到定位之后的delegate方法中,然后我查看了一下手机上对应用的定位权限界面,发现我的应用的访问用户的地理位置的权限是 ...
  • 本报讯(记者 尹磊)微软中国近日发布了一项对目前市场上盗版Windows 7的测试报告,测试结果显示,93%的被测样本具有潜在风险.6月10日,微软携手产业合作伙伴在武汉宣布,将通过网络媒体.电视.平面媒体广告和户外 ...
  • 检查日期和时间 Web页面访问会留下详细时间,它是由服务器生成的而非客户端时间,不能随意更改,因而可根据时间高低频度为站点生成相应报告. 跟踪客户端IP地址 这对地理信息查询相当有用,大多数日志分析软件能基于IP地址 ...
  • 记下来,免得下次再发冤枉时间. Log4Net写入到数据库配置过程中的一些小问题备忘 Log4Net 日志配置[附带源码]
  • 部分创业板首批候选企业及其保荐机构正努力加快回答证监会反馈函问题的进度,预计本周上交答复.根据目前进度,首批创业板企业的挂牌时间可能较预期提前. 反馈函的答复速度将影响创业板总体进度.一位证监会相关部门人士此前表示, ...
  •   <oracle大型数据库系统在AIX/unix上的实战详解>讨论26:关于自动工作量档案(AWR)的相关信息查询      文平 集中几条用户问题:没有启动 DB Console,怎么看AWR报告? ...
  • AIX下面 0,2,4,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,58 * * * * /usr/sap/trans ...
  • 你需要QA,但是需要投入多少?在软件世界有两类风险:死于"凌迟"和死于重大事故 QA是规避风险的好办法,两种风险都很严重,所以大部分人做投资的时候两种风险都规避.我们在后续的博客中会仔细分析这两种 ...