Java ThreadPoolExecutor[提交超过MaxPoolSize的文件]

Java ThreadPoolExecutor[提交超过MaxPoolSize的文件],java,multithreading,java-8,threadpool,Java,Multithreading,Java 8,Threadpool,我有一个应用程序,允许用户批量添加水印的图像。该应用程序将只使用一个线程,一次只能添加一个水印 我希望用户能够更改一次运行的水印任务[线程]的数量:可能是设置中的[1-5],我不能使用fixedThreadPool,因为它具有固定的池大小 我研究了如何使用线程池执行器私有静态线程池执行器executor=(ThreadPoolExecutor)Executors.newCachedThreadPool()

我有一个应用程序,允许用户批量添加水印的图像。该应用程序将只使用一个线程,一次只能添加一个水印

我希望用户能够更改一次运行的水印任务[线程]数量:可能是设置中的[1-5],我不能使用fixedThreadPool,因为它具有固定的池大小

我研究了如何使用线程池执行器
私有静态线程池执行器executor=(ThreadPoolExecutor)Executors.newCachedThreadPool()newMaxThreadCount

现在,当我尝试将say15个图像水印任务提交给最大池大小为3的执行者时, 我得到以下例外情况:

java.util.concurrent.RejectedExecutionException:Task com.darkmental.zeondownloader.app.main.phototools.watermark.BulkWatermarkTask$$Lambda$710/1861585081@1e2d8ad4已从java.util.concurrent中拒绝。ThreadPoolExecutor@24d02747[正在运行,池大小=3,活动线程=3,排队任务=0,已完成任务=0]

我希望ThreadPoolExecutor具有与fixedThreadPool相同的行为,其中我可以拥有10的池大小,并且仍然提交我想要的任务,但我没有。我该怎么做呢?

看看这些节目,这种行为是故意的

当execute方法(java.lang.Runnable)中提交的新任务被关闭时,以及当executer对最大线程和工作队列容量使用有限界限且饱和时,将拒绝该方法(java.lang.Runnable)

因此,在您的情况下,您的队列似乎已满或不接受任何新项目。 我还没有看到您实际上是如何创建
ThreadPoolExecutor
,但我想,您需要在构造函数中指定一个足够的
BlockingQueue

编辑:这可能会发生,因为
Executors.newCachedThreadPool()
是无界的,如果没有可用的缓存线程,则每次都会创建一个新线程。但是,设置最大池大小会对此产生干扰,任务将通过
RejectedExecutionHandler
被拒绝

我目前无法重现该场景,但您可能可以通过
setRejectedExecutionHandler(ThreadPoolExecutor.CallerRunPolicy)
将活动的
AbortPolicy
更改为
ThreadPoolExecutor.CallerRunPolicy
。这将导致调用线程执行新任务,而不是抛出异常。

查看显示,这种行为是有意的

当execute方法(java.lang.Runnable)中提交的新任务被关闭时,以及当executer对最大线程和工作队列容量使用有限界限且饱和时,将拒绝该方法(java.lang.Runnable)

因此,在您的情况下,您的队列似乎已满或不接受任何新项目。 我还没有看到您实际上是如何创建
ThreadPoolExecutor
,但我想,您需要在构造函数中指定一个足够的
BlockingQueue

编辑:这可能会发生,因为
Executors.newCachedThreadPool()
是无界的,如果没有可用的缓存线程,则每次都会创建一个新线程。但是,设置最大池大小会对此产生干扰,任务将通过
RejectedExecutionHandler
被拒绝


我目前无法重现该场景,但您可能可以通过
setRejectedExecutionHandler(ThreadPoolExecutor.CallerRunPolicy)
将活动的
AbortPolicy
更改为
ThreadPoolExecutor.CallerRunPolicy
。这将导致调用线程执行新任务,而不是引发异常。

谢谢,我编辑了我的问题。我使用Executors.newCachedThreadPool()@RafatRifaie创建了它。我编辑了我的答案以反映这一点。您可能应该考虑使用一个简单的<代码>执行器。我不认为线程的创建是一个很大的开销,你会从使用缓存池中获益,这有一个缺点。谢谢你,我编辑了我的问题。我使用Executors.newCachedThreadPool()@RafatRifaie创建了它。我编辑了我的答案以反映这一点。您可能应该考虑使用一个简单的<代码>执行器。我认为线程创建的开销不会太大,使用缓存池会带来好处,但缓存池有这个缺点。当需要
ThreadPoolExecutor
时,应该使用
newthreadpoolexecutor(…)
并且不要滥用故意指定更抽象返回类型的工厂方法。如果需要
ThreadPoolExecutor
,则应使用
新ThreadPoolExecutor(…)
,并且不要滥用故意指定更抽象返回类型的工厂方法。