当我尝试访问同步列表时,为什么我的线程会停止?

Jus*_*tin 1 java synchronized

由于某种原因,这个输出:

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

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

ska*_*man 6

有东西锁定任务.根据这种应用程序的类型,您应该能够获得系统的完整堆栈转储,但方法会有所不同.例如,我认为大多数基于Windows的应用程序服务器上的CTRL-Break都会这样做,我认为在linux上发送SIGQUIT会做同样的事情.

一旦获得堆栈转储,您可以查看它以尝试找出哪个其他线程对该对象具有锁定.

您还可以使用VisualVM获取堆栈转储,以实现相同的最终目标:

在本地应用程序运行时,您可以使用Java VisualVM进行线程转储(堆栈跟踪).进行线程转储不会停止应用程序.当您打印线程转储时,您将获得包含Java线程的线程状态的线程堆栈的打印输出.

在Java VisualVM中打印线程转储时,该工具会打印应用程序活动线程的堆栈跟踪.在没有应用程序的命令行控制台的情况下,使用Java VisualVM进行线程转储非常方便.您可以使用堆栈跟踪来帮助诊断许多问题,例如死锁或应用程序挂起时.