java cachedThreadPool 杀死提交的线程

标签 java multithreading

我需要做一些多线程工作,我使用 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);

但即使工作未完成且不等待,它也只会终止我的线程。

也许是因为我在每个线程中创建了一个新实例 new FontParser().fontSearcher(content, url);

最佳答案

I call my ContentParser.queueExecutor from another class, so after all jobs are submitted I do:

这听起来像是有人在调用 cachedThreadPool.shutdown() 但作业仍在提交到池中。那永远不应该发生。 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 字段。您无法控制外部类如何(或在这种情况下何时)调用池中的关键方法。我会将其设为私有(private),然后在您的 ContentParser 类上使用 await 方法:

private static ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
...
public static void awaitPoolTermination(/* maybe timeout args here */) {
    cachedThreadPool.awaitTermination(5l, TimeUnit.MINUTES);
}

这可以更好地控制您的线程池,并且不允许在不适当的地方关闭。那么 ContentParser 方法的调用者将首先调用 contentParser.queueExecutor(...) 然后调用 contentParser.awaitPoolTermination(...).

关于java cachedThreadPool 杀死提交的线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31746310/

相关文章:

单个面板的 Java Swing GlassPane 功能?

java - 生成 6 个不相等数字的循环失败 (java)

multithreading - 如何使用Delphi和OmniThread在后台将文件上传到azure?

java - 为什么在这种特殊情况下向 JList 添加元素会使其为空?

java - 为未检查的错误编写错误消息?

Java乘法表

java - 使用 Javax.comm 重新枚举 java 中的所有串行设备

python - python 中的线程 exit_request

Javascript - 函数在函数完成之前返回变量?

java - 在线程中维护与服务器的连接?