ExecutorService永远不会停止,不会有异常

时间:2011-12-05 10:11:17

标签: java exception concurrency

我采用了this post的并发策略。然而我的看起来像这样:

ExecutorService executorService = Executors.newFixedThreadPool(NUMBER_OF_CREATE_KNOWLEDGE_THREADS);
List<Callable<Collection<Triple>>> todo = new ArrayList<Callable<Collection<Triple>>>(this.patternMappingList.size());
for (PatternMapping mapping : this.patternMappingList ) {
    todo.add(new CreateKnowledgeCallable(mapping, i++));
}
try {

    List<Future<Collection<Triple>>> answers = executorService.invokeAll(todo);
    for (Future<Collection<Triple>> future : answers) {

        Collection<Triple> triples = future.get();
        this.writeNTriplesFile(triples);
    }    
}
catch (InterruptedException e) { ... }
catch (ExecutionException e) { ... }

executorService.shutdown();
executorService.shutdownNow();

但ExecutorService永远不会关闭。我试图调试完成了多少CreateKnowledgeCallable,但是这个数字似乎有所不同(在没有执行新线程/ callables但服务仍在运行之后)。我确信记录并打印出每个可能的异常,但我看不到有一个异常。似乎在一段时间之后,除了之外没有任何事情发生,因为NUMBER_OF_CREATE_KNOWLEDGE_THREADS cpus永远在100%旋转。我究竟做错了什么? 如果您需要更具体的信息,我很乐意为您提供!

亲切的问候, 丹尼尔

4 个答案:

答案 0 :(得分:3)

执行shutdownNow()时,它会中断池中的所有线程。但是,如果您的代码忽略中断,它们将不会停止。您需要使用

等测试使您的任务荣誉中断
while(!Thread.currentThread.isInterrupted()) {

}

Thread.sleep(0);

答案 1 :(得分:0)

executorService.invokeAll

只有在所有任务完成后才会返回。和future.get()一样 您确定,对executorService.invokeAll(todo);的调用是否会永远返回而不是永远等待任务完成?

答案 2 :(得分:0)

你确定你提交的任务实际完成了吗?如果您检查shutdownNow()shutdown()的API,则会发现他们不保证会终止。

您是否尝试使用awaitTermination(long timeout, TimeUnit unit)来调用具有合理时间的超时参数? (编辑:“合理的时间量”当然取决于你的任务的平均处理时间以及你要求终止时执行的任务数量)

Edit2:我希望我自己的代码中的以下示例可能会帮助您(请注意,它可能不是解决此问题的最佳或最优惠的方法)

try {

        this.started = true;
        pool.execute(new QueryingAction(pcqs));
        for(;;){
            MyObj p = bq.poll(timeout, TimeUnit.MINUTES); // poll from a blocking queue

            if(p != null){
                if (p.getId().equals("0"))
                    break;

                pool.submit(new AnalysisAction(ds, p, analyzedObjs));
            }else 
                drc.log("Timed out while waiting...");

        }

      } catch (Exception ex) {
          ex.printStackTrace();

      }finally{
          drc.log("--DEBUG: Termination criteria found, shutdown initiated..");
          pool.shutdown();

          int mins = 2;
          int nCores = poolSize -1 ;
          long  totalTasks = pool.getTaskCount(), 
                compTasks = pool.getCompletedTaskCount(),
                tasksRemaining = totalTasks - compTasks,
                timeout = mins * tasksRemaining / nCores;

          drc.log(  "--DEBUG: Shutdown commenced, thread pool will terminate once all objects are processed, " +
                    "or will timeout in : " + timeout + " minutes... \n" + compTasks + " of " +  (totalTasks -1) + 
                    " objects have been analyzed so far, " + "mean process time is: " +
                    drc.getMeanProcTimeAsString() + " milliseconds.");

          pool.awaitTermination(timeout, TimeUnit.MINUTES);
      }

答案 3 :(得分:0)

每个遇到此类问题的人都应该尝试在没有并发的情况下实现相同的算法。在这个方法的帮助下,我发现一个组件抛出了一个被吞下的运行时异常。