2017-03-01 174 views
0

我试图在WebServer中实现ExecutorCompletionService,这个WebServer将具有多个主机并且将从多个客户端调用。分布式环境中的ExecutorCompletionService.take()方法

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

现在假设这样的场景:

  1. 从方法调用的实例1:我提交5个任务,以服务于工作。

  2. 从方法调用的实例2:我提交6个任务并行从其他客户端的服务。

  3. 从实例1:我拨打executorCompletionService.take() 5次。

是否有任何保证,当从同一实例调用时,我会得到与实例1中提交的任务相对应的值?

请注意,我只是取消了当时的任务,并且我的固定线程池始终保持活动状态。

回答

0

我觉得这条线从文档约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 

} 
+0

那你究竟通过使执行人作为单身的意思吗?如何获得这些特定的未来价值? –

+0

执行者可以在ExecutorCompletionServices中共享。你会得到正确的值,因为你将拥有多个这些服务。 – john16384

+0

为什么让执行者单身人士会工作?我的意思是说这个 让我们用20个线程来执行单身人士,现在我们仍然有20个线程可以使用。现在我们将在每个线程池中实例化CompletionService。同样的情况可能会再次发生,实例1给出了5个任务,实例2给出了同一个执行者的5个任务。现在使用take()方法,我们最终可能会从另一个实例获取其中一项任务。如何让多个服务避免这种情况?每个服务是否跟踪它提交给执行者的未来或者听到直到找到第一个任务? –