出于某种原因,输出:
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();
}
只需输出“GantryAgent:尝试打印'任务'......”,但不能打印以下任何消息。我猜测线程在尝试访问同步列表'任务'时会以某种方式“卡住”,但我不知道为什么会发生这种情况。
'tasks'被声明并初始化为:
private List<BinToDump> tasks =
Collections.synchronizedList(new ArrayList<BinToDump>());
有人能说出我错过的东西吗?
啊!我怀疑我可能有罪魁祸首:
/* If nothing left to do, return to original position. */
synchronized (tasks) {
if (tasks.isEmpty()) {
doReturnToOriginalPos();
}
}
在我的调度程序中(这是代理设计),我检查'tasks'是否为空,然后调用doReturnToOriginalPos()。也许这只是一次又一次地发生,以至于其他方法没有机会修改它?
确实是问题所在!在我的调度程序中,它一直被调用得如此之快,以至于没有别的东西可以访问“任务”谢谢大家的帮助!
答案 0 :(得分:6)
某些东西锁定了任务。根据这种应用程序的类型,您应该能够获得系统的完整堆栈转储,但方法会有所不同。例如,我认为大多数基于Windows的应用程序服务器上的CTRL-Break都会这样做,我认为在linux上发送SIGQUIT会做同样的事情。
一旦获得堆栈转储,您可以查看它以尝试找出哪个其他线程锁定该对象。
您也可以使用VisualVM获取堆栈转储,以达到相同的最终目标:
您可以使用Java VisualVM来获取 线程转储(堆栈跟踪)而a 本地应用程序正在运行拿一个 线程转储不会停止 应用。打印线程时 dump你得到一个线程的打印输出 包含线程状态的堆栈 Java线程。
在Java中打印线程转储时 VisualVM,该工具打印一个堆栈 跟踪活动线程的痕迹 应用。使用Java VisualVM来实现 拿一个线程转储可以很 在没有的情况下很方便 有一个命令行控制台 应用。您可以使用堆栈跟踪 帮助诊断一些问题 比如死锁或什么时候 应用程序挂起。
答案 1 :(得分:2)
是否有可能另一个线程正在对tasks
进行同步锁定?