【问题标题】:How to debug a multi-threaded app in IntelliJ?如何在 IntelliJ 中调试多线程应用程序?
【发布时间】:2015-01-05 17:07:27
【问题描述】:

我在 IntelliJ IDEA 14.0.2 中遇到了多个线程和断点的奇怪问题。断点之后的代码在停止之前执行。

import java.util.concurrent.atomic.AtomicInteger;


public class Main {

    private static final int NUM_CLIENTS = 1000;

    static class TestRunnable implements Runnable {
        AtomicInteger lock;
        @Override
        public void run() {
            synchronized (this.lock) {
                int curCounter = this.lock.addAndGet(1);
                System.out.println("Thread: " + Thread.currentThread().getName() + "; Count: " + curCounter);
                if (curCounter >= NUM_CLIENTS) {
                    lock.notifyAll();
                }
            }
        }
    }

    public static void main(final String args[]) {
        final AtomicInteger lock = new AtomicInteger(0);
        for (int i = 0; i < NUM_CLIENTS; i++) {
            TestRunnable tr1 = new TestRunnable();
            tr1.lock = lock;
            new Thread(tr1).start();
        }
        synchronized (lock) {
            try {
                lock.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Main woken up");
        }
    }
}

当我在第 12 行设置断点(全部暂停)时,synchronized (this.lock)System.out.println 仍会执行(有时会执行多次)。截图如下:

据我所知,所有线程都应该在断点处停止。

【问题讨论】:

  • 如果将断点放在第 14 行会怎样? (println)
  • 我可以向你保证,一个线程已经停止...哪个线程未确定。
  • 这只是因为建立套接字连接需要一些时间。并且调试器需要建立连接才能在 JVM 中安装断点。对于这个时间很关键的情况(就像你的情况一样),有一个 JVM 选项可以暂停 JVM,直到建立连接。你的 IDE 应该有一个激活它的选项。
  • @David Schwartz:这将是一个奇怪的限制。例如。 Eclipse 没有这样的问题。而且从来没有。
  • @David Schwartz:显示当前堆栈跟踪的视图仅显示多个堆栈跟踪。实际上,该视图始终向您显示具有层次结构的树:“已启动的 JVM”→“正在运行的线程”→“堆栈跟踪”,因为您始终可以单击线程或 JVM 手动挂起线程或整个 JVM …

标签: java multithreading debugging intellij-idea


【解决方案1】:

文档读起来令人困惑,但this is the relevant block. 归根结底是将属性设置为在线程上挂起,而不是在整个应用程序上挂起。这将导致您在每个单独的线程而不是任意的、不确定的线程上打断点。

  • 暂停策略:全部
    • 遇到断点时,所有线程都会暂停。
  • 暂停策略:线程
    • 当断点被命中时,断点所在的线程被挂起。

【讨论】:

  • 事实上,我想在任何线程遇到断点时暂停所有线程。就像 Eclipse 一样。我想这是不可能的?
  • 事实上文档说:“全部 - 当一个断点被命中时,所有线程都被挂起”。这正是我想要的行为。问题是一些线程,有时,在断点被击中后继续执行,可能是当 IDEA 停止第一个线程击中断点时。我认为这只是 IDEA 调试器或 JVM 上的一个错误。他们至少应该澄清文档中的行为,因为它完全是错误的,而不是令人困惑的。
  • 无论如何你的解决方案现在对我有用,非常感谢。
  • 文档(针对 2017.2)还描述:“在某些情况下,IntelliJ IDEA 不会在断点处停止。考虑以下情况:在类的不同方法处设置两个断点,并且它们的暂停策略设置为全部。当其中一个断点被命中时,会执行一些单步操作。如果在单步执行另一个线程时遇到第二个断点,IntelliJ IDEA 将不会停在那里。"
  • 升级到 2018.2 后我仍然看到该行为。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多