2015-01-15 138 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