0

假设我有几个任务要在 Java 中并行运行。每个任务都返回成功或失败。每个任务都有一个相关的截止日期。如果一个任务在截止日期前没有完成,它会被中断(所有任务都是可中断的)并返回失败。

如果其中一项任务失败(即返回失败),我们会中断所有其他仍在运行的任务。

我们应该等到所有任务完成,最后如果所有任务都返回成功则返回成功,或者如果至少一个任务返回失败则返回失败。

你将如何实施它?我将使用util.concurrent。您会建议哪些库原语?

4

2 回答 2

1

我会使用ExecutorServicewithCountDownLatch和一个接口数组列表Future来保存任务:

List<List<String>> elements = MyPartition.partition(bigObjectList, size); 
List<Future<?>> tasks = new ArrayList<Future<?>>();
ExecutorService executor = Executors.newFixedThreadPool(4);
CountDownLatch doneSignal =  new CountDownLatch(10);
for(List<String> l: elements) {         
   ReadTask worker = new ReadTask(doneSignal, l);
   tasks.add(executor.submit(worker));
}   

long timeout = 10000;
doneSignal.await(timeout, TimeUnit.MINUTES);
boolean notFinished = false;
if(doneSignal.getCount() > 0) {
  for(Future<?> fut : tasks) {
    if(!fut.isDone()) {
      System.out.println("Sub Thread " + fut + " has not finshed!");
      fut.cancel(true);             
      notFinished = true;
    }
  }
}
于 2013-04-09T10:17:59.070 回答
1

ExecutorCompletionService 似乎最接近

    ExecutorService ex = Executors.newCachedThreadPool();
    ExecutorCompletionService<Boolean> cs = new ExecutorCompletionService<Boolean>(
            ex);
    List<Callable<Boolean>> tasks = new ArrayList<Callable<Boolean>>();
       ... add tasks
    List<Future<Boolean>> futures = new ArrayList<Future<Boolean>>();
    for (Callable<Boolean> t : tasks) {
        futures.add(cs.submit(t));
    }
    for (!futures.isEmpty()) {
        try {
            Future<Boolean> f = cs.poll(1, TimeUnit.SECONDS);
            futures.remove(f);  // poll returns the same instance of Future as in the futures list
            if (f == null || !f.get()) {  // poll returns null on timeout
                break;
            }
        } catch (Exception e) {
            break;
        }
    }
    // cancel remaining tasks, if all finished OK the list will be empty
    for (Future<Boolean> future : futures) {
        future.cancel(true);
    }
于 2013-04-09T10:42:36.600 回答