我开发的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.