【发布时间】: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