我正在尝试在具有多个主机并从多个客户端调用的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
}