Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java cachedThreadPool杀死提交的线程_Java_Multithreading - Fatal编程技术网

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(…)

是否确定所有线程都已终止?如果线程完成并且池关闭完成,“等待终止”也会返回…对不起,我想可能出现了一些异常,但我没有注意到。我需要检查。如果您没有异常,其他可能的原因是:等待终止方法中的超时不足。请确保超时时间足够长,以便在该时间段内完成已提交的任务