我有一个Java客户端需要递归调用服务器来检索大型数据图 - 需要大约一千个调用。我无法控制服务器,这对于时间要求严格的崩溃恢复方案是必需的。
我的问题是我需要阻止原始线程直到所有呼叫都完成。
java.util.concurrent中的RecursiveAction和ForkJoinPool抽象正是我所需要的,除了它们是为CPU并行性而设计的,并且禁止使用阻塞I / O.
那么,实施递归网络调用的最佳方法是什么,启动线程阻塞直到所有调用都完成?
其他背景信息:
其他想法:与ThreadPoolExecutor一起使用单相Phaser是否合适?呼叫任务将调用Phaser.register(),进行呼叫,提交子任务,然后调用Phaser.arrive()。启动线程将调用Phaser.awaitAdvance(1)。这是最合适的方法吗?
答案 0 :(得分:4)
使用JDK1.7 Phasers可以很好地工作。我使用的模式是这样的:
private void loadGraphFromServer() {
final Phaser phaser = new Phaser(1); // "1" registers the calling thread
for (final Item item : getDataListFromServer()) {
phaser.register();
executorService.submit(new Runnable() {
public void run() {
try {
getMoreDataFromServer(item.getSomeId());
// more nested loops/tasks/calls here...
}
finally {
phaser.arrive();
}
}
});
}
phaser.arriveAndAwaitAdvance(); // blocks until all tasks are complete
}
答案 1 :(得分:0)
我会尝试使用固定大小的执行程序池。您可以将最大大小设置为10到30个线程并将其与所有1000个请求进行批量处理,或者添加1个请求以创建另外两个,以及另外两个等等。您可以等待所有这些请求完成,使用shutdown()和awaitTermination ()