当前位置: 首页 > news >正文

SynchronousQueue的不恰当使用,瞬时过载导致线程池任务被拒绝

设计实现是要求在服务启动时,创建一批常驻线程,从阻塞队列里取元素执行业务逻辑。为此我刚开始使用的代码如下:
使用CommandLineRunner在服务启动时创建好线程

public class ConflictFactory implements CommandLineRunner{

  private static final int CD_EXECUTOR_THREAD = Runtime.getRuntime().availableProcessors();

  private static final ThreadPoolExecutor CD_EXECUTOR = new ThreadPoolExecutor(
														  CD_EXECUTOR_THREAD, 
														  CD_EXECUTOR_THREAD, 
														  0L,
														  TimeUnit.MILLISECONDS, 
														  new SynchronousQueue<>(), 
														  new NamedThreadFactory("CD-", false),
														  new ThreadPoolExecutor.AbortPolicy());

  static {
     CD_EXECUTOR.prestartAllCoreThreads();
  }

  @Override
  public void run(String... args) throws Exception {
      for (int i = 0; i < CD_EXECUTOR_THREAD; i++) {
          CD_EXECUTOR.execute(() -> {
              while (true) {
                  try {
                      node = singleDomainQueue.take();
                      、、、、、、
                  } catch (Exception e) {
                      、、、、、、
                  }
              }
          });
      }
   }
}

运行时偶发报错,提示任务被拒绝
在这里插入图片描述
创建的任务数量=核心线程数量为什么 任务还会被拒绝呢?

虽然使用了prestartAllCoreThreads()预先创建线程,但是当任务提交时,线程还未全部创建完毕,active threads = 1,还未达到CD_EXECUTOR_THREAD个。由于SynchronousQueue的特性 :

  • 不会存储任务,必须由 某个线程立即消费,否则任务会被拒绝。
  • 线程的创建、任务提交、任务执行 必须完全同步,否则任务会失败

瞬时过载导致任务被拒绝。

还是老老实实换成了LinkedBlockingQueue,暂存一下任务,等线程逐步创建完成再执行。

  private static final ThreadPoolExecutor CD_EXECUTOR = new ThreadPoolExecutor(
													  CD_EXECUTOR_THREAD, 
													  CD_EXECUTOR_THREAD, 
													  0L,
													  TimeUnit.MILLISECONDS, 
													  new LinkedBlockingQueue<>(CD_EXECUTOR_THREAD + 3), 
													  new NamedThreadFactory("CD-", false),
													  new ThreadPoolExecutor.AbortPolicy());

SynchronousQueue只适合任务数量<最大线程数量,并且线程已经是就绪状态的场景。高吞吐、低延迟,但适用于短时任务,线程池需要足够的线程数,否则任务会被拒绝

在这里插入图片描述


在这里插入图片描述

相关文章:

  • 【hadoop】hadoop streaming
  • Vue3动态加载组件,警告:Vue received a Component than was made a reactive object
  • nginx-rtmp-module之ngx_rtmp.c代码详解
  • 使用 Chromedp 监听网页请求和响应
  • 利用脚本和Shader制作屏幕后处理效果
  • MOSN(Modular Open Smart Network)-04-TLS 安全链路
  • HCIA复习
  • go-zero: sqlx 对timestamp 格式数据问题
  • 罗杰斯特回归
  • 四川省汽车加气站操作工备考题库及答案分享
  • 蓝桥杯练习题--一年中的第几天
  • Numpy基础
  • LLM 加速技术有哪些
  • Linux--文件
  • “Failed to load steamui.dll” 文件丢失:原因分析与全面修复指南
  • UE5小石子阴影在非常近距离才显示的问题
  • 告别Win10强制更新:永久关闭系统更新指南
  • Node.js 下载安装及环境配置教程、卸载删除环境配置超详细步骤(附图文讲解!) 从零基础入门到精通,看完这一篇就够了
  • Day16 -实例:Web利用邮箱被动绕过CDN拿真实ip
  • 鸿蒙生态全解析:应用适配分享
  • 银行积分大幅贬值遭质疑,涉及工行、中行、农行等
  • 雷军内部演讲回应质疑:在不服输、打不倒方面,没人比我们更有耐心
  • 一图看懂|印巴交火后,双方基地受损多少?
  • 普京确定俄乌谈判俄方代表团名单
  • 陈吉宁龚正黄莉新胡文容等在警示教育基地参观学习,出席深入贯彻中央八项规定精神学习教育交流会
  • 巴方:印度上周导弹袭击造成至少40名平民死亡