一个线程池Java的多个CompletionService

一个线程池Java的多个CompletionService,java,concurrency,completion-service,Java,Concurrency,Completion Service,我正在使用以下体系结构开发Java服务器应用程序: 客户端向服务器发出RPC请求 我相信RPC服务器(gRPC)有自己的线程池来处理请求 请求会立即插入线程池1,以进行更多处理 我们将调用request R,一个特定的请求类型需要并行运行一些异步任务,判断结果以形成一个共识,即它将返回到客户端。这些任务的运行时间较长,因此我使用单独的线程池2来处理这些请求。重要的是,每个请求R都需要运行相同的2-3个异步任务线程池2因此为所有当前正在执行的请求R提供服务。但是,请求R应该只能查看和检索属于它的

我正在使用以下体系结构开发Java服务器应用程序:

  • 客户端向服务器发出RPC请求
  • 我相信RPC服务器(gRPC)有自己的线程池来处理请求
  • 请求会立即插入
    线程池1
    ,以进行更多处理
  • 我们将调用
    request R
    ,一个特定的请求类型需要并行运行一些异步任务,判断结果以形成一个共识,即它将返回到客户端。这些任务的运行时间较长,因此我使用单独的
    线程池2
    来处理这些请求。重要的是,每个
    请求R
    都需要运行相同的2-3个异步任务<代码>线程池2因此为所有当前正在执行的
    请求R
    提供服务。但是,
    请求R
    应该只能查看和检索属于它的异步任务
  • 为了实现这一点,在每个传入的
    请求R
    时,当其位于
    线程池1
    中时,它将为请求创建一个新的
    完成服务
    ,由
    线程池2
    支持。它将提交2-3个异步任务,并检索结果。这些请求应该与
    线程池2
    中运行的属于其他请求的任何其他请求严格隔离
  • 我的问题是:
    • 首先,Java的
      CompletionService
      是孤立的吗?在检查了文档之后,我找不到关于这个的好文档。换句话说,如果两个或两个以上的
      CompletionService
      由同一线程池支持,它们中的任何一个是否有可能拖累属于另一个
      CompletionService
      的未来
    • 其次,为每个请求创建这么多的
      CompletionService
      ,这是一种糟糕的做法吗?有没有更好的方法来处理这个问题?当然,为每个请求创建一个新的线程池不是一个好主意,那么有没有更规范/正确的方法来隔离
      CompletionService
      中的未来,或者我正在做的事情还好吗
提前谢谢你的帮助。如能提供任何有用的文档或示例,将不胜感激

代码,仅供参考,尽管很琐碎:

公共静态最终执行器服务线程池2=
新的ThreadPoolExecutor(16,64,60,TimeUnit.SECONDS,新的LinkedBlockingQueue());
//为处理请求程序而创建,RequestRHandler在线程池1中运行
公共类请求处理程序{
完成服务cs;
RequestRHandler(){
cs=新的ExecutorCompletionService(线程池2);
}
字符串执行(){
提交(1);
提交(2);
提交(3);
//假设asyncTask3首先完成
Future asyncTask3Result=cs.take();
//asyncTask3结果表示asyncTask1和asyncTask2结果无所谓,请取消它们
//没有检查结果
//取消所有期货,我跟踪此请求中提交的所有期货并取消它们,
//因此,它不应该影响tp2池中的任何其他请求
取消所有期货(cs);
返回asyncTask3Result.get();
}
}
首先,Java的
CompletionService
是孤立的吗

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

其次,为每个请求创建这么多的
CompletionService
s,这是一种糟糕的做法吗

我得说没关系。
CompletionService
不过是围绕执行者的一个相当薄的包装。您必须承受“开销”(任务的内部
BlockingQueue
和包装器实例),但它很小,而且您可能从中获得的比成本更多。有人可能会问,你是否需要一个只用于2到3项任务,但这取决于任务。在这一点上,这是一个关于
CompletionService
是否值得的问题,所以这取决于您的决定,因为它超出了您的问题范围