2017-03-01 176 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()方法,我們最終可能會從另一個實例獲取其中一項任務。如何讓多個服務避免這種情況?每個服務是否跟蹤它提交給執行者的未來或者聽到直到找到第一個任務? –