我有这样的代码:
public void testThreads() throws Exception {
MyThreadManager mgr = createAndStartMyManager();
Thread t1 = createMyThread(mgr, 1);
Thread t2 = createMyThread(mgr, 2);
t1.start();
t2.start();
//do some checks
t1.join();
t2.join();
}
使用MyThreadManager
线程进行操作,并且可以随时中断其中的任何一个。因为这是测试用例的一部分,我需要调试正在运行的线程,所以我添加了joins
了让测试等待完成我的调试(JUnit 在测试完成时断开调试器)。
问题是,在某些情况下连接挂起 -jstack
输出是这样的:
at java.lang.Object.wait(Native Method)
- waiting on <0xeec68eb0> (a java.lang.Thread)
at java.lang.Thread.join(Thread.java:1143)
- locked <0xeec68eb0> (a java.lang.Thread)
at java.lang.Thread.join(Thread.java:1196)
at MyClass.testThreads(MyClass.java:100)
并且根据join
JDK(我使用 1.6.0_07)实现,线程似乎只是在调用isAlive
和wait
(在源代码中标记)之间完成:
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
// -----> here ???? <------
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
我对 ThreadPoolExecutor 和 FutureTask 进行了同样的尝试,但行为是相同的(它挂起)。
所以我的问题是,如果我对比赛条件是真的,以及如何在没有任何挂起的情况下清楚地加入线程......
谢谢