由于某种原因,这个输出:
public void msgNeedParts() {
// Blabla...
System.out.println(name + ": Try to print 'tasks'...");
synchronized(tasks) {
System.out.println(name + ": Tasks--" + tasks);
System.out.println(name + ": Did I manage to print it?");
tasks.add(new BinToDump(feeder, binNum));
}
stateChanged();
}
Run Code Online (Sandbox Code Playgroud)
只需打印出"GantryAgent:尝试打印'任务'......",但不能打印出以下任何消息.我猜测线程在尝试访问同步列表'任务'时会以某种方式"卡住",但我不知道为什么会发生这种情况.
'tasks'被声明并初始化为:
private List<BinToDump> tasks =
Collections.synchronizedList(new ArrayList<BinToDump>());
Run Code Online (Sandbox Code Playgroud)
任何人都可以指出我错过了什么吗?
啊! 我怀疑我可能有罪魁祸首:
/* If nothing left to do, return to original position. */
synchronized (tasks) {
if (tasks.isEmpty()) {
doReturnToOriginalPos();
}
}
Run Code Online (Sandbox Code Playgroud)
在我的调度程序(这是代理设计)中,我检查'tasks'是否为空,然后调用doReturnToOriginalPos().也许这只是一次又一次地发生,以至于其他方法没有机会修改它?
这确实是问题所在!在我的调度程序中,它一直被调用得如此之快,以至于没有别的东西可以访问"任务" 谢谢大家的帮助!
有东西锁定任务.根据这种应用程序的类型,您应该能够获得系统的完整堆栈转储,但方法会有所不同.例如,我认为大多数基于Windows的应用程序服务器上的CTRL-Break都会这样做,我认为在linux上发送SIGQUIT会做同样的事情.
一旦获得堆栈转储,您可以查看它以尝试找出哪个其他线程对该对象具有锁定.
您还可以使用VisualVM获取堆栈转储,以实现相同的最终目标:
在本地应用程序运行时,您可以使用Java VisualVM进行线程转储(堆栈跟踪).进行线程转储不会停止应用程序.当您打印线程转储时,您将获得包含Java线程的线程状态的线程堆栈的打印输出.
在Java VisualVM中打印线程转储时,该工具会打印应用程序活动线程的堆栈跟踪.在没有应用程序的命令行控制台的情况下,使用Java VisualVM进行线程转储非常方便.您可以使用堆栈跟踪来帮助诊断许多问题,例如死锁或应用程序挂起时.
| 归档时间: |
|
| 查看次数: |
255 次 |
| 最近记录: |