java - Java ThreadPoolExecutor [提交的内容超过MaxPoolSize]

标签 java multithreading java-8 threadpool

我有一个应用程序,允许用户批量向图像添加水印。该应用程序只会使用一个线程,并且一次只能添加一个水印。
我希望用户能够更改水印 任务[线程] 一次运行的数字:设置中可能是 [1-5] ,我不能使用fixedThreadPool,因为它具有固定的池大小。
我调查了使用 ThreadPoolExecutor private static ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool();的情况,每次用户更改线程数时,我都会调用ThreadPoolExecutor.setMaxPoolSize( newMaxThreadCount )。
现在,当我尝试向执行者提交 15个图像水印任务时,最大池大小为 3
我得到以下异常:

java.util.concurrent.RejectedExecutionException: Task com.darkmental.zeondownloader.app.main.phototools.watermark.BulkWatermarkTask$$Lambda$710/1861585081@1e2d8ad4 rejected from java.util.concurrent.ThreadPoolExecutor@24d02747[Running, pool size = 3, active threads = 3, queued tasks = 0, completed tasks = 0]


我希望 ThreadPoolExecutor 具有与 fixedThreadPool 相同的行为,其中我可以将的池大小设置为10 ,并且仍可以提交任意数量的任务,但我没有。我怎样才能做到这一点?

最佳答案

查看JavaDoc可以看出,此行为是有意的。

New tasks submitted in method execute(java.lang.Runnable) will be rejected when the Executor has been shut down, and also when the Executor uses finite bounds for both maximum threads and work queue capacity, and is saturated.


因此,在您的情况下,您的队列似乎已满或不接受任何新项目。
我还没有看到您实际上是如何创建ThreadPoolExecutor的,但是我想,您需要在构造函数中指定足够的BlockingQueue
编辑:可能会发生这种情况,因为Executors.newCachedThreadPool()是无界的,并且如果没有可用的缓存线程,则每次都会创建一个新线程。但是,设置最大池大小会对此产生干扰,并且该任务会通过RejectedExecutionHandler拒绝。
我目前无法重现该场景,但是您可以通过AbortPolicy将 Activity 的ThreadPoolExecutor.CallerRunsPolicy更改为setRejectedExecutionHandler(ThreadPoolExecutor.CallerRunsPolicy)。这导致调用线程执行新任务,而不是引发异常。

关于java - Java ThreadPoolExecutor [提交的内容超过MaxPoolSize],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64418418/

相关文章:

用于查找 "contains"的 Java 8 lambda 表达式

java - 复制(通过 Web API)完成;不管怎样,我的 pipe 坏了。怎么解决呢?

java - 如何使用外部对象的按钮在组件上执行操作?

java - Android Videoview 视频看不到

java - 如何在 Java 8 上编译 Eclipse 库

java - 使用 lambda 表达式将 hashmap 保存到 String

java - 如何根据鼠标位置在折线图上绘制十字准线

java - 限制在java中同时执行的最大线程数

java - JFrame 立即关闭

java - Java中有多个线程访问同一方法时的线程安全性