我创建了一些工作流程如何等待我创建的所有线程。此示例适用于 99% 的情况,但有时 waitForAllDone 方法完成的时间早于所有线程完成的时间。我知道这一点是因为在 waitForAllDone 之后我正在关闭使用创建的线程的流,因此会发生异常
Caused by: java.io.IOException: Stream closed
我的线程开始于:
@Override
public void run() {
try {
process();
} finally {
Factory.close(this);
}
}
结束:
protected static void close(final Client client) {
clientCount--;
}
当我创建线程时,我称之为:
public RobWSClient getClient() {
clientCount++;
return new Client();
}
和工厂内的 clientCount 变量:
private static volatile int clientCount = 0;
等待:
public void waitForAllDone() {
try {
while (clientCount > 0) {
Thread.sleep(10);
}
} catch (InterruptedException e) {
LOG.error("Error", e);
}
}
最佳答案
您需要通过synchronized
保护clientCount
的修改和读取。主要问题是 clientCount--
和 clientCount++
不是原子操作,因此两个线程可以执行 clientCount--
/clientCount++
并最终得到错误的结果。
像上面那样简单地使用 volatile
只有在字段上的所有操作都是原子操作的情况下才有效。因为它们不是,所以您需要使用一些锁定机制。正如 Anton 所说,AtomicInteger
是一个很好的选择。请注意,它应该是 final
或 volatile
以确保它不是线程本地的。
话虽如此,Java 1.5 后的一般规则是使用 ExecutorService
而不是 Threads
。将此与 Guava 的 Futures
类结合使用可以使等待所有内容完成变得如此简单:
Future<List<?>> future = Futures.successfulAsList(myFutureList);
future.get();
// all processes are complete
关于java - 如何等待所有线程完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13473070/