【问题标题】:Why does my thread stop when I try to access a synchronized list?当我尝试访问同步列表时,为什么我的线程会停止?
【发布时间】:2009-12-01 08:31:16
【问题描述】:

由于某种原因,输出如下:

 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: Try to print 'tasks'...”,但不会打印以下任何消息。我猜测线程在尝试访问同步列表“任务”时会以某种方式“卡住”,但我不知道为什么会这样。

'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();

        }

    }

在我的调度程序(这是一个代理设计)中,我检查“任务”是否为空,然后调用 doReturnToOriginalPos()。也许这只是一次又一次地发生得太快以至于其他方法没有机会修改它?

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

【问题讨论】:

  • 发布所有访问“任务”集合的代码。您在某个地方锁定了对它的访问权限,或者出现了死锁。
  • 除了声明/初始化之外,我发布的代码应该是第一次访问“任务”,但我会努力发布其余部分。

标签: java synchronized


【解决方案1】:

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

获得堆栈转储后,您可以查看它以尝试找出哪个其他线程对该对象进行了锁定。

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

您可以使用 Java VisualVM 来获取 线程转储(堆栈跟踪),而 本地应用程序正在运行。采取 线程转储不会停止 应用。当你打印线程 转储你得到线程的打印输出 包含线程状态的堆栈 Java 线程。

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

【讨论】:

  • 有时 JVisualVM 绝对是救命稻草。
【解决方案2】:

是否有可能另一个线程持有针对tasks 的同步锁?

【讨论】:

  • 啊哈!感谢您指出这一点-我检查了: System.out.println(Thread.holdsLock(tasks)); ...它返回 false。
  • @FallSe7en:该方法仅检查 current 线程是否持有锁(您已经知道它没有,因为它在获取时永远阻塞:-))。如果您使用 Java 6 运行,启动 VisualVM 或 JConsole,连接到您的进程,您将能够看到哪个线程持有锁(及其堆栈跟踪)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-15
  • 2016-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多