Java 服务永远不会停止,没有例外

Java 服务永远不会停止,没有例外,java,exception,concurrency,Java,Exception,Concurrency,我采用了来自的并发策略。但是我的看起来是这样的: ExecutorService executorService = Executors.newFixedThreadPool(NUMBER_OF_CREATE_KNOWLEDGE_THREADS); List<Callable<Collection<Triple>>> todo = new ArrayList<Callable<Collection<Triple>>>(thi

我采用了来自的并发策略。但是我的看起来是这样的:

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 ExecutorService=Executors.newFixedThreadPool(创建知识线程的数量);
List todo=newarraylist(this.patternMappingList.size());
用于(PatternMapping映射:this.patternMappingList){
添加(新的CreateKnowledgeCallable(映射,i++);
}
试一试{
列表答案=executorService.invokeAll(todo);
关于(未来:答案){
集合三元组=future.get();
此.writentriples文件(三个);
}    
}
捕获(中断异常e){…}
捕获(执行异常){…}
executorService.shutdown();
executorService.shutdownNow();
但Executor服务从未关闭。我试图调试完成了多少CreateKnowledgeCallable,但这个数字似乎有所不同(在没有执行新线程/Callable但服务仍在运行之后)。我确信记录并打印了每一个可能的异常,但我看不到有任何异常发生。似乎过了一段时间,除了CPU的创建线程数永远以100%的速度旋转之外,再也没有什么事情发生了。我做错了什么? 如果您需要更具体的信息,我很乐意为您提供

亲切问候,,
Daniel

执行Shutdownow()时,它会中断池中的所有线程。但是,如果您的代码忽略了中断,它们将不会停止。您需要通过以下测试使您的任务尊重中断

while(!Thread.currentThread.isInterrupted()) {

}

应仅在所有任务完成后返回。以及
future.get()

您确定吗,对
executorService.invokeAll(todo)的调用是否返回,而不是永远等待任务完成的块?

您确定提交的任务确实完成了吗?如果您检查API,您会发现它们不保证终止

您是否尝试过使用具有合理时间长度的调用作为超时参数?(编辑:“合理时间”当然取决于任务的平均处理时间以及在您要求终止时执行的任务数量)

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


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

是的,我知道,这是等待所有组件完成的关键。你的任务是否捕获InterruptedException?如果你的意思是CreateKnowledgeCallable With task,那么否,它们只捕获Lucene抛出的异常。据我所知,shutdown()(在shutdownNow()之前调用)让提交到executor服务的所有线程都完成。我不会在所有线程都应该完成后添加线程。有趣的是,这并不总是超时。我只是将线程数从20个减少到10个(服务器上有32个内核)脚本运行到
this.writeNTriplesFile(三元组);
但仅适用于274个线程中的105个。通过调用shutdown,它可以防止新任务,并在所有任务完成后关闭。shutdownNow()返回所有未执行的任务。我的猜测是,某个任务正在引发异常,您没有等待未执行的任务完成,因此Shutdownow会阻止其余任务运行。也就是说,您的try-catch在循环外等待将来的结果,而不是在循环内。但是程序不应该退出吗?同样有些线程以100%的cpu功率运行,根本不做任何工作(lucene搜索、solr索引查询)。此外,我宁愿等待,然后使用
shutdownNow
这更像是一种调试/实验性的代码行。对不起,但我如何将代码粘贴到这里?你的意思是
future.get()
应该用try/catch来包围吗?还有一个问题,据我所知,
invokeAll()
等待所有线程完成。既然所有线程都完成了,那么
future.get()
怎么会被中断?你说的“确定”是什么意思有没有一种合适的方法来检查它们是否在一段时间内完成?没有,我没有尝试使用a waittermination()`由于我需要所有答案。我试图给出一个可能描述我的意思的示例,请参见上面编辑的答案。Thx@posdef我想我明白你的意思。但我不想等待指定的时间。我知道代码最终会完成。我从“自己做每件事解决方案”切换到了“自己做每件事”此executor服务,但现在它不再工作:(我第一次尝试线程池时也遇到过类似的问题,但最终还是通过上述方法解决了。我假设您实施了producet消费者策略,您确定您的终止条件已满足吗?很抱歉,这些问题很琐碎,但在处理并发时会出现神奇的错误,所以任何事情都是p。)我通常编写一个(或多个)测试用例,在没有并发的情况下运行算法。
Thread.sleep(0);
executorService.invokeAll
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);
      }