java cachedThreadPool杀死提交的线程
我需要做一些多线程工作,我使用java cachedThreadPool杀死提交的线程,java,multithreading,Java,Multithreading,我需要做一些多线程工作,我使用ExecutorService.newCachedThreadPool()并提交从队列中检索到的一些作业 public class ContentParser { public static ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); // ... public static void queueExecutor(Content content)
ExecutorService.newCachedThreadPool()
并提交从队列中检索到的一些作业
public class ContentParser {
public static ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
// ...
public static void queueExecutor(Content content) {
String url = "";
while ((url = queue.poll()) != null){
LOG.info("Picked url " + url);
cachedThreadPool.submit(new ParserCallable(content, url));
}
}
// ...
private static class ParserCallable implements Runnable {
private Content content;
private String url;
private ParserCallable(Content content, String url) {
this.url = url;
this.content = content;
}
@Override
public void run(){
new FontParser().fontSearcher(content, url);
}
}
因此,每个线程都会创建一个新的FontParser
实例,我在其中做了一些工作
我从另一个类调用我的ContentParser.queueExecutor
,因此在提交所有作业后,我会:
ContentParser.cachedThreadPool.shutdown();
ContentParser.cachedThreadPool.awaitTermination(5l, TimeUnit.MINUTES);
但它只是杀死我的线程,即使工作没有完成,没有等待
可能是因为我创建了一个新实例newFontParser().fontSearcher(内容,url)代码>在每个线程中
我从另一个类调用ContentParser.queueExecutor,因此在提交所有作业后,我会:
ContentParser.cachedThreadPool.shutdown();
ContentParser.cachedThreadPool.awaitTermination(5l, TimeUnit.MINUTES);
听起来像是说有人在调用cachedThreadPool.shutdown()
,但作业仍在提交到池中。这永远不应该发生<代码>关机()
只应在poll()循环完成后调用
我建议您在queueExecutor(…)
方法中执行以下操作:
while ((url = queue.poll()) != null){
LOG.info("Picked url " + url);
cachedThreadPool.submit(new ParserCallable(content, url));
}
// shutdown _after_ all jobs have been submitted
cachedThreadPool.shutdown();
另外,一般来说,将字段公开是一种不好的做法,尤其是在本例中,您的cachedThreadPool
字段。您无法控制外部类如何(或在本例中何时)调用池中的关键方法。我会将其设置为私有,然后在您的ContentParser
类上有一个wait方法:
private static ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
...
public static void awaitPoolTermination(/* maybe timeout args here */) {
cachedThreadPool.awaitTermination(5l, TimeUnit.MINUTES);
}
这样可以更好地控制线程池,并且不允许在不适当的位置关闭。因此,ContentParser
方法的调用方将首先调用ContentParser.queueExecutor(…)
,然后调用ContentParser.waitingpooltermination(…)是否确定所有线程都已终止?如果线程完成并且池关闭完成,“等待终止”也会返回…对不起,我想可能出现了一些异常,但我没有注意到。我需要检查。如果您没有异常,其他可能的原因是:等待终止方法中的超时不足。请确保超时时间足够长,以便在该时间段内完成已提交的任务