ThreadPoolTaskExecutor导致feeder线程永久阻塞问题求助
问题原因分析
你的代码只打印到60就停止,核心原因是任务提交被拒绝,导致加载线程异常终止:
accountDeletionTaskExecutor的配置是:核心线程10、最大线程10、队列容量50。这意味着线程池最多能同时运行10个任务,队列缓存50个等待任务,总共可容纳60个任务(10+50)。- 当加载线程提交第61个任务时,队列已满,且无法创建新线程(最大线程数已达上限),此时ThreadPoolTaskExecutor默认采用
AbortPolicy拒绝策略——直接抛出RejectedExecutionException。 - 加载线程的lambda代码没有捕获这个异常,导致线程直接终止,后续的
customerAccountIds就再也不会被提交处理了。
另外你提到“期望加载线程在submit时阻塞”,但默认情况下submit()方法是非阻塞的,它只会把任务扔进队列(或分配线程),不会等待任务执行完成。
解决方案
根据你的需求(加载线程提交任务时,若线程池忙则阻塞,直到能提交为止),可以用以下几种方式解决:
方案一:使用CallerRunsPolicy拒绝策略
这个策略会让提交任务的线程(也就是你的加载线程)直接执行当前无法提交的任务,相当于让加载线程“帮忙干活”,自然会阻塞住后续任务的提交,直到当前任务执行完毕。
修改accountDeletionTaskExecutor的配置:
ThreadPoolTaskExecutor accountDeletionTaskExecutor = new ThreadPoolTaskExecutor(); accountDeletionTaskExecutor.setCorePoolSize(10); accountDeletionTaskExecutor.setMaxPoolSize(10); accountDeletionTaskExecutor.setQueueCapacity(50); // 添加拒绝策略配置 accountDeletionTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); accountDeletionTaskExecutor.initialize();
方案二:自定义阻塞式拒绝策略
如果不想让加载线程参与任务执行,只想让它阻塞等待队列有空位,可以自定义拒绝策略,利用阻塞队列的put()方法(队列满时会阻塞):
accountDeletionTaskExecutor.setRejectedExecutionHandler((runnable, executor) -> { try { // 阻塞等待队列有空位,再放入任务 executor.getQueue().put(runnable); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new RuntimeException("任务提交被中断", e); } });
方案三:使用无界队列(谨慎使用)
去掉队列容量限制,让队列可以无限容纳任务(但要注意内存溢出风险,如果任务量极大可能导致OOM):
// 不设置queueCapacity,默认使用无界的LinkedBlockingQueue ThreadPoolTaskExecutor accountDeletionTaskExecutor = new ThreadPoolTaskExecutor(); accountDeletionTaskExecutor.setCorePoolSize(10); accountDeletionTaskExecutor.setMaxPoolSize(10); accountDeletionTaskExecutor.initialize();
额外建议:你代码最后一行Thread.currentThread().join();没有实际作用(主线程等待自己相当于死循环),可以改成等待线程池任务全部完成后再关闭:
// 等待加载线程完成所有任务提交 accountLoaderTaskExecutor.shutdown(); accountLoaderTaskExecutor.awaitTermination(1, TimeUnit.HOURS); // 等待删除任务线程池完成所有任务 accountDeletionTaskExecutor.shutdown(); accountDeletionTaskExecutor.awaitTermination(1, TimeUnit.HOURS);
内容的提问来源于stack exchange,提问作者kms333
相关产品推荐
相关产品推荐

