如何在Java中动态调整缓存线程池的大小

3
我目前正在使用futures进行异步线程处理,我希望它的功能类似于“cachedThreadPool”,但也能够完成以下两个任务:
  1. 每次成功完成线程时,增加允许的最大线程数。

  2. 如果线程抛出异常或超时,则减少允许的最大线程数。

在自定义的 ThreadPoolExecutor 中是否有可能实现这一点?我是第一次这样使用Executors,因此指导我正确的方向将对解决问题很有帮助。

https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html#setMaximumPoolSize(int) ? - Philip Whitehouse
谢谢回复,我知道那个方法,但我需要知道在哪里调用它?比如线程抛出异常的情况下,我如何从我的自定义类中检索当前最大值并将其递增? - GreenGodot
有一个 getMaximumPoolSize() 方法。您可以通过覆盖 afterExecute 方法来处理线程池中未捕获的异常。 - Philip Whitehouse
抱歉再次发帖,但基本上,自定义线程池如何知道其中一个线程抛出了异常? - GreenGodot
一个线程中发生的异常不会影响线程池的大小。这里建议处理当线程池为空时分散线程的问题。 - Ryan J
1
出于好奇,您为什么想要增加线程池大小?项目将排队等待直到有可用的线程。如果这是因为您计划生成子线程并将它们添加到池中,则可能希望使用Java 8中新引入的ForkJoinPool - Powerlord
1个回答

2
动态调整线程池大小需要仔细考虑。如果您遇到超时并且您的响应是减少线程数,假设任务可以并行处理,这可能会使问题变得更糟。
无论如何,在此处提供一段代码,当任务抛出异常并使其完成成功时,它将更改池的大小。
class ManagedThreadPoolExecutor extends ThreadPoolExecutor {
      @Override
      protected void afterExecute(Runnable r, Throwable t) {
           if(t != null)
                setMaximumPoolSize(getMaximumPoolSize()-1);
           else
                setMaximumPoolSize(getMaximumPoolSize()+1);

      }
}

那段代码会减小池的大小,但实际上不会正确地设置大小。getMaximumPoolSize()--在递减之前返回原始计数。应该使用--getMaximumPoolSize()++getMaximimumPoolSize() - Ryan J
@RyanJ 我稍微修改了一下,因为这让我感到困惑。 - Philip Whitehouse
注意,目前我只是在做实验。我也会尝试Powerlord的建议。我现在感到非常愚蠢,因为我错过了afterExecute方法中可抛出参数的存在。 - GreenGodot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接