2015-01-15 193 views
0

我正在運行的服務器應用程序獲取多個請求,這些請求是我想要使用任務系統處理的任務。Executor:等待特定任務完成

每個任務都表示爲Runnable,這將要求n線程池中的線程數量,其中n小於或等於線程池大小。線程池當然是必要的,以便而不是過多的CPU線程太多。

但是,其中一些任務可以是多線程的,有些則不能。這就是爲什麼一個任務可能需要等待所有特定線程完成以便合併來自這些線程的結果以獲得最終結果。

如果一個使用多個Thread情況下,人們可能會加入那些像這樣:

try { 
    // Wait for all threads to finish their tasks 
    for (Thread thread : threads) { 
     thread.join(); 
    } 
} catch (InterruptedException e) { 
    e.printStackTrace(); 
} 

// Finish job here .. 

,但我需要像這樣使用類似java.util.concurrent.Executor或任何一個線程池的作品。

+0

我可能是錯在這裏,但感覺就像你使用上的抽象水平錯誤執行人。如果你有一個需要* n *個線程運行的任務,我建議你讓這個任務創建它自己的線程池,或者把它分解成更小的1線程任務。 – aioobe

+0

@aioobe你可能會遇到太多效率不高的執行者/池 – bachr

+0

在開始工作之前,可以讓每個任務都做一些SharedSemaphore.acquire(n)。 – aioobe

回答

1

如果我理解正確的話,你需要像這樣(但你的架構似乎太複雜):

class MyTask implements Runnable { 
    @Override 
    public void run() { 
     // some work 
    } 
} 

之後:

ExecutorService executorService = Executors.newFixedThreadPool(2000); 
ArrayList<Future> futures = new ArrayList<>(); 

futures.add(executorService.submit(new MyTask())); 
futures.add(executorService.submit(new MyTask())); 
futures.add(executorService.submit(new MyTask())); 

for (Future future: futures) { 
    try { 
     future.get(100, TimeUnit.SECONDS); 
    } catch (Throwable cause) { 
     // process cause 
    } 
} 

每個的Future.get()將等待任務結束(本例中最多100秒)。

+0

我認爲這個任務應該實現'Callable'而不是'Runnable'以便將來 – bachr

+0

@arbi是的,如果結果很重要的話。 – DmitryKanunnikoff

+0

但是如果某些任務只需要一個線程,那麼在啓動下一個任務之前等待它們完成是沒有意義的。 – aioobe

1

可以使用ExecutorServiceCyclicBarrier沿着每個任務如下:

public class ThreadedTask implements Runnable { 
    CyclicBarrier barrier; 
    public ThreadedTask(CyclicBarrier barrier) { 
     this.barrier = barrier; 
    } 
    @Override 
    public void run() { 
     // do something 
     barrier.await(); 
    } 
} 
ExecutorService executor = Executors.newFixedThreadPool(pool_size); 
... 
CyclicBarrier barrier = new CyclicBarrier(n+1); 
for(int i=0; i<n; i++) { 
    // launch all tasks 
    executor.submit(new ThreadedTask(barrier)); 
} 
// waits for the tasks to finish or timeout 
barrier.await(seconds, TimeUnit.SECONDS); 
+0

這看起來不像我所需要的。我不想等待所有線程。我想等待一組由特定任務執行的線程。你的回答似乎在等待所有執行的任務。 – displayname

+0

不是真的,...之後的部分是任務的主體(當你的任務實現'Runnable'時,我在'run()'中假設)。如果你想使用強大的屏障概念,這只是一種選擇。 – bachr

+0

好吧,現在我明白了!這也是我的問題的有效解決方案,但我會去爲另一個。無論如何+1 – displayname