You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 07:35:36