ExecutorCompletionservice

ExecutorCompletionservice

我正在尝试在具有多个主机并从多个客户端调用的ExecutorCompletionService中实现WebServer

我的问题与ExecutorCompletionService.take()方法的实现有关。我的ExecutorCompletionService声明是一个固定池大小为20线程的单例,作为弹簧注入bean的一部分。

现在假设这种情况:


从方法调用的实例1:我向服务提交5个任务以进行处理。
从方法调用的实例2:我从其他客户端并行向服务提交6个任务。
从实例1:我打executorCompletionService.take() 5次。


从同一个实例调用时,是否可以保证获得与在实例1中提交的任务相对应的值?

请注意,我只是在结束时取消任务,而我的固定线程池始终保持活动状态。

最佳答案

我认为文档中有关ExecutorCompletionService的这一行很关键:


  该类足够轻巧,适合在以下情况下短暂使用
  处理任务组


换句话说,它轻巧到足以使它成为请求范围的对象,甚至成为局部变量或字段。

因此,您不应该真正使它成为单例,因为您怀疑,它不会区分从一个请求/线程或另一个请求/线程提交的任务。

取而代之的是,使Executor为单例,并为所有ExecutorCompletionService共享。

更新资料

@Inject private Executor executor;  // can be singleton

public void someMethod() {
    ExecutorCompletionService ecs1 = new ExecutorCompletionService(executor);
    ExecutorCompletionService ecs2 = new ExecutorCompletionService(executor);

    // ExecutorCompletionService should be scoped per instance

    ecs1.submit(task1)
    ecs1.submit(task2);
    ecs1.submit(task3);

    ecs2.submit(task4)
    ecs2.submit(task5);
    ecs2.submit(task6);

    // ecs1 `take` will only return tasks submitted to ecs1
    // ecs2 `take` will only return tasks submitted to ecs2

}

10-02 07:08