由于某种原因,此输出:

 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()。也许这只是一遍又一遍地发生,以至于其他方法没有机会修改它?

确实是问题所在!在我的调度程序中,它一直被调用得如此之快,以至于没有其他东西可以访问“任务”。谢谢大家的帮助!

最佳答案

某些东西可以锁定任务。根据这是哪种类型的应用程序,您应该能够获得系统的完整堆栈转储,但是方法会有所不同。例如,我认为大多数基于Windows的应用服务器上的CTRL-Break都可以做到这一点,并且我认为在Linux上发送SIGQUIT可以做到这一点。

一旦获得了堆栈转储,就可以浏览它以尝试找出哪个其他线程对该对象具有锁定。

对于相同的最终目标,您还可以使用VisualVM获得堆栈转储:


  您可以使用Java VisualVM进行
  线程转储(堆栈跟踪)时
  本地应用程序正在运行。以
  线程转储不会停止
  应用。当您打印线时
  转储,您将获得线程的打印输出
  包含线程状态的堆栈
  Java线程。
  
  在Java中打印线程转储时
  VisualVM,该工具可打印堆栈
  的活动线程的痕迹
  应用。使用Java VisualVM来
  进行线程转储可以非常
  如果您不方便的话
  有一个命令行控制台
  应用。您可以使用堆栈跟踪
  帮助诊断许多问题
  例如死锁或
  应用程序挂起。

10-07 19:34
查看更多