Java ThreadPoolExecutor[提交超过MaxPoolSize的文件]
我有一个应用程序,允许用户批量添加水印的图像。该应用程序将只使用一个线程,一次只能添加一个水印 我希望用户能够更改一次运行的水印任务[线程]的数量:可能是设置中的[1-5],我不能使用fixedThreadPool,因为它具有固定的池大小 我研究了如何使用线程池执行器Java ThreadPoolExecutor[提交超过MaxPoolSize的文件],java,multithreading,java-8,threadpool,Java,Multithreading,Java 8,Threadpool,我有一个应用程序,允许用户批量添加水印的图像。该应用程序将只使用一个线程,一次只能添加一个水印 我希望用户能够更改一次运行的水印任务[线程]的数量:可能是设置中的[1-5],我不能使用fixedThreadPool,因为它具有固定的池大小 我研究了如何使用线程池执行器私有静态线程池执行器executor=(ThreadPoolExecutor)Executors.newCachedThreadPool()
私有静态线程池执行器executor=(ThreadPoolExecutor)Executors.newCachedThreadPool()每次用户更改线程数时,我都调用ThreadPoolExecutor.setMaxPoolSize(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(…)
,并且不要滥用故意指定更抽象返回类型的工厂方法。