当前位置: 首页 > 知识库问答 >
问题:

java cachedThreadPool终止提交的线程

訾凯歌
2023-03-14

我需要做一些多线程工作,并使用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.queue执行器,所以在提交所有作业后,我这样做:

ContentParser.cachedThreadPool.shutdown();
ContentParser.cachedThreadPool.awaitTermination(5l, TimeUnit.MINUTES);

但它只会杀死我的线程,即使工作没有完成,也没有等待。

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

共有1个答案

姜弘新
2023-03-14

我从另一个类调用我的ContentParser.queue执行者,所以在提交所有作业后,我这样做:

听起来好像有人在调用cachedThreadPool。shutdown()但作业仍在提交到池中。这不应该发生<代码>关机()只能在循环完成后调用。

我建议在您的queueExecitor(...)方法中执行以下操作:

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.queueExecitor(...),然后调用contentParser.awaitPoolTermer(...)

 类似资料:
  • 主要内容:1 什么是Java终止线程,2 Thread类终止线程的方法,3 Java终止线程的例子1,4 Java终止线程的例子2,5 Java终止线程的例子3,6 isInterrupted和interrupted方法1 什么是Java终止线程 如果任何线程处于睡眠或等待状态(即,调用sleep()或wait()方法),则在线程上调用interrupt()方法,会抛出InterruptedException中断睡眠或等待状态。如果线程未处于睡眠或等待状态,则调用interrupt()方法将执行

  • 问题内容: 当我测试创建子线程的方法的执行时,JUnit测试会在子线程之前终止并杀死它。 我如何强制JUnit等待子线程完成其执行? 谢谢 问题答案: 阅读问题和评论后,似乎您需要的是 一种对异步操作进行单元测试的技术 。doSomething()立即返回,但是您希望测试代码等待其完成,然后进行一些验证。 问题在于该测试无法识别该调用所产生的线程,因此显然它无法等待它们。人们可以想到许多复杂的(可

  • 请帮助我处理这个主线程/父线程将触发子线程。如果我们停止父线程/主线程,它还必须停止所有子线程/子线程 我想用中断做这件事,但做不到。请帮我把代码弄出来 以及如何确保所有子线程都已停止?有什么办法也可以做到这一点吗 提前谢谢! 我正在尝试这样做: 公共类ThreadTest1扩展Thread{私有静态最终记录器LOGGER=Logger.get记录器(mylogger); }

  • 我正在寻找一种方法来停止/杀死线程,我看到Thread.stop()已被弃用。所以我开始寻找另一个解决方案,并看到多个帖子建议这样做: 但这不会阻止我的线程,我的线程看起来像这样: 有人得到我可以用来停止/杀死我的线程的解决方案吗?非常感谢任何帮助。

  • 问题内容: 与此问题相关,我有以下代码可订阅redispubsub队列,并使用__init__中提供的处理程序将消息提供给处理它们的类: 在上面的链接问题中,请注意,如果断开连接,则永不返回。因此,尽管我的函数可以被调用,但它实际上不会导致线程终止,因为它挂在对线程内部的调用上。 链接问题的可接受答案提到了黑客入侵redis-py的连接池。我真的不想这样做,并且有一个分支版本的redis- py(