一个线程池的多个 CompletionService Java

Multiple CompletionService for one thread pool Java

我正在开发具有以下一般架构的 Java 服务器应用程序:

在此先感谢您的帮助。非常感谢任何指向有用文档或示例的指针。

代码,供参考,虽然琐碎:

public static final ExecutorService THREAD_POOL_2 =
        new ThreadPoolExecutor(16, 64, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>());

// Gets created to handle a RequestR, RequestRHandler is run in Thread Pool 1
public class RequestRHandler {

    CompletionService<String> cs;

    RequestRHandler() {
        cs = new ExecutorCompletionService<>(THREAD_POOL_2);
    }

    String execute() {
        cs.submit(asyncTask1);
        cs.submit(asyncTask2);
        cs.submit(asyncTask3);

       // Lets say asyncTask3 completes first
      Future<String> asyncTask3Result = cs.take();

      // asyncTask3 result indicates asyncTask1 & asyncTask2 results don't matter, cancel them
      // without checking result


      // Cancels all futures, I track all futures submitted within this request and cancel them,
      // so it shouldn't affect any other requests in the TP 2 pool
      cancelAllFutures(cs);


      return asyncTask3Result.get();  
    }


}

Firstly, is Java's CompletionService isolated?

这不是保证,因为它是一个接口,因此实现决定了这一点。但由于唯一的实现是 ExecutorCompletionService 我只想说答案是:是的。 ExecutorCompletionService 的每个实例在内部都有一个 BlockingQueue,已完成的任务在其中排队。实际上,当您在服务上调用 take 时,它只是通过调用 take 将调用传递到队列。每个提交的任务都由另一个对象包装,完成后将任务放入队列中。因此每个实例管理它提交的与其他实例隔离的任务。

Secondly, is this bad practice to be creating this many CompletionServices for each request?

我会说没关系。 CompletionService 只不过是执行程序的一个相当薄的包装器。您必须忍受“开销”(任务的内部 BlockingQueue 和包装器实例),但它很小,您从中获得的收益可能远远超过成本。有人可能会问您是否只需要一个来完成 2 到 3 个任务,但这在某种程度上取决于任务。在这一点上,问题是 CompletionService 一般而言是否值得,所以这由您决定,因为它超出了您的问题范围。