Java 带有阻塞I/O的RecursiveAction/ForkJoinPool

Java 带有阻塞I/O的RecursiveAction/ForkJoinPool,java,concurrency,Java,Concurrency,我有一个Java客户机,它需要递归地调用服务器来检索一个大的数据图——需要大约1000个调用。我无法控制服务器,这是时间关键型崩溃恢复场景所必需的 我的问题是,我需要阻止我的原始线程,直到所有调用都完成 来自java.util.concurrent的RecursiveAction和ForkJoinPool抽象正是我所需要的,只是它们是为CPU并行而设计的,并且禁止使用阻塞I/O 那么,实现递归网络调用的最佳方法是什么,在所有调用完成之前启动线程阻塞 其他上下文信息: 我无法修改服务器 服务器允

我有一个Java客户机,它需要递归地调用服务器来检索一个大的数据图——需要大约1000个调用。我无法控制服务器,这是时间关键型崩溃恢复场景所必需的

我的问题是,我需要阻止我的原始线程,直到所有调用都完成

来自java.util.concurrent的RecursiveAction和ForkJoinPool抽象正是我所需要的,只是它们是为CPU并行而设计的,并且禁止使用阻塞I/O

那么,实现递归网络调用的最佳方法是什么,在所有调用完成之前启动线程阻塞

其他上下文信息:

  • 我无法修改服务器
  • 服务器允许并支持这种繁重的查询
  • 我将把并发网络调用的数量限制在10-30个左右
  • 在磁盘上缓存数据是不可行的

其他想法:单相移相器是否适合与ThreadPoolExecutor结合使用?调用任务将调用Phaser.register(),进行调用,提交子任务,然后调用Phaser.arrival()。启动线程将调用Phaser.awaitAdvance(1)。这是最合适的方法吗?

我会尝试使用固定大小的执行器池。您可以将最大大小设置为10到30个线程,并将其与所有1000个请求一起打包,或者添加一个请求,创建两个以上的请求,以及这两个以上的请求。您可以使用shutdown()和waittermination()等待所有这些请求完成。

我将尝试使用固定大小的执行器池。您可以将最大大小设置为10到30个线程,并将其与所有1000个请求一起打包,或者添加一个请求,创建两个以上的请求,以及这两个以上的请求。您可以使用shutdown()和waittermination()等待所有这些请求完成。

使用JDK1.7相量器可以很好地实现这一点。我使用的模式是这样的:

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
}

使用JDK1.7相量器可以很好地工作。我使用的模式是这样的:

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
}

谢谢,但我不能使用shutdown/awaitTermination,因为启动线程不知道上一个任务何时提交。每个任务都可以等待它创建的任务。它可以进行尾部优化,也就是说,如果这是它最后要做的事情,就不要再创建另一个任务。但这样我的线程就用完了。。。除非我遗漏了什么。谢谢,但我不能使用shutdown/waittermination,因为启动线程不知道上一个任务何时提交。每个任务都可以等待它创建的任务。它可以进行尾部优化,也就是说,如果这是它最后要做的事情,就不要再创建另一个任务。但这样我的线程就用完了。。。除非我遗漏了什么。