java 线程池默认提供了几种拒绝策略:

这几个策略都实现了RejectedExecutionHandler,拿DiscardOldestPolicy来说,查看源码:

核心代码只有2行:

  • e.getQueue().poll() 从列表里弹出1个(最早的)任务,以便让队列空出1个位置
  • e.execute(r) 新任务放入队列执行

从这段代码来看,如果有任务被丢弃(即:从队列里弹出了),不会有任何报错,也没有日志可查,实际使用中不太方便监控这种情况。

我们可以参考这段源码,自定义策略:

import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor; public class CustomDiscardPolicy implements RejectedExecutionHandler { //额外传入1个名称,方便打日志或埋点监控时,定位问题
private String factoryName = ""; public CustomDiscardPolicy(String factoryName) {
this.factoryName = factoryName;
} public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
if (!e.isShutdown()) {
Runnable poll = e.getQueue().poll();
//这里可以加一些自己的处理(比如:埋点监控)
System.err.println("[" + this.factoryName + "]task will be discard:" + poll);
e.execute(r);
}
}
}

当然,这里出于演示目的,只打了一行错误信息,实际应用中大家可以埋点发到kafka之类(以便后续做实时监控预警)。

测试一下:

    @Test
public void testThreadPool() throws InterruptedException {
final ThreadFactory DEMO_THREAD_FACTORY = new ThreadFactoryBuilder().setNameFormat("demo-POOL-%d").build(); final ExecutorService DEMO_POOL = new ThreadPoolExecutor(1, 2, 300L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(5), DEMO_THREAD_FACTORY, new CustomDiscardPolicy("demo-POOL")); for (int i = 0; i < 10; i++) {
DEMO_POOL.submit(() -> {
try {
System.out.println(Thread.currentThread().getId() + " ready!");
//假设线程干活,需要一段时间
Thread.sleep(500);
System.out.println("\t" + Thread.currentThread().getId() + " done!");
} catch (Exception e) {
}
});
}
//等一会儿,让线程池都跑完,再结束main
Thread.sleep(10000);
}

提交了10个任务,线程池必然饱和(10>2+5),会丢弃一些早期任务,输出如下:

从输出看,丢了3个任务,符合预期。

java线程池使用小技巧:自定义拒绝策略的更多相关文章

  1. 线程池ThreadPoolExecutor里面4种拒绝策略

    ThreadPoolExecutor类实现了ExecutorService接口和Executor接口,可以设置线程池corePoolSize,最大线程池大小,AliveTime,拒绝策略等.常用构造方 ...

  2. Java线程池实现原理之自定义线程池(一)

    1.队列的概念 谈到多线程先讲下队列的概念,之后的多线程学习会用到此类知识. 队列分为:阻塞式队列(有界).非阻塞式队列(无界),遵循着先进先出.后进后出的原则.阻塞队列与非阻塞队列区别: 1.非阻塞 ...

  3. JUC之线程池的实现原理以及拒绝策略

    线程池实现原理 向线程池提交任务后,线程池如何来处理这个任务,之前我们了解了7个参数,我们通过这些参数来串联其线程池的实现原理. 1.在创建了线程池后,开始等待请求 2.当调用execute()方法添 ...

  4. java线程池(newSingleThreadExecutor())小应用

    创建单个线程,用来操作一个无界的队列任务,不会使用额外的线程.如果线程崩溃会重新创建一个,直到任务完成. 代码: import java.util.concurrent.ExecutorService ...

  5. 按照阿里巴巴规范创建Java线程池

    前言 Executors Executors 是一个Java中的工具类.提供工厂方法来创建不同类型的线程池. 常用方法: 1.newSingleThreadExecutor   介绍:创建一个单线程的 ...

  6. Java 线程池原理分析

    1.简介 线程池可以简单看做是一组线程的集合,通过使用线程池,我们可以方便的复用线程,避免了频繁创建和销毁线程所带来的开销.在应用上,线程池可应用在后端相关服务中.比如 Web 服务器,数据库服务器等 ...

  7. SpringBoot线程池和Java线程池的实现原理

    使用默认的线程池 方式一:通过@Async注解调用 public class AsyncTest { @Async public void async(String name) throws Inte ...

  8. 一个基于Java线程池管理的开源框架Hippo4j实践

    @ 目录 概述 定义 线程池痛点 功能 框架概览 架构 部署 Docker安装 二进制安装 运行模式 依赖配置中心 接入流程 个性化配置 线程池监控 无中间件依赖 接入流程 服务端配置 三方框架线程池 ...

  9. 深入理解Java线程池:ScheduledThreadPoolExecutor

    介绍 自JDK1.5开始,JDK提供了ScheduledThreadPoolExecutor类来支持周期性任务的调度.在这之前的实现需要依靠Timer和TimerTask或者其它第三方工具来完成.但T ...

  10. java 线程池第一篇 之 ThreadPoolExcutor

    一:什么是线程池? java 线程池是将大量的线程集中管理的类,包括对线程的创建,资源的管理,线程生命周期的管理.当系统中存在大量的异步任务的时候就考虑使用java线程池管理所有的线程.减少系统资源的 ...

随机推荐

  1. 36.7K star!拖拽构建AI流程,这个开源LLM应用框架绝了!

    36.7K star!拖拽构建AI流程,这个开源LLM应用框架绝了! 只需拖拽节点,5分钟搭建专属AI工作流! Flowise 是一款革命性的低代码LLM应用构建工具,开发者通过可视化拖拽界面,就能快 ...

  2. 【代码】C语言|保留小数点后n位并四舍五入,便于处理运算和存储不善的浮点数

    前言 有个人跟我说浮点数运算起来非常麻烦,总是算着算着丢失精度,导致计算结果取int的时候取不准.毕竟系统也没有自动根据这个数的精度四舍五入的功能. 比如int(2.999999999999999)= ...

  3. 通过DirectXTK,将.obj,.fbx,.dae,等常见三维格式,转换为.cmo格式

    (1)下载DirectXTK项目:https://github.com/microsoft/DirectXTK (2)VS 打开该项目,右键项目,生成依赖性-自定义 (3)勾选MeshContentT ...

  4. Jenkins 起服务包后自动退出

    今天使用Jenkins来做一个定时更新并启java服务包的任务,搞了挺久. 比较坑爹的就是,我的jar包有十几个,各个包也比较大,每次启动都要好久. 但启完最后一个包之后,我去,Jenkins就结束了 ...

  5. 怒更一波TransDuck免费的声音克隆和AI配音功能

    宝子们! 最近咱软件TransDuck的免费声音克隆和AI配音功能被大家用爆啦!感谢各位自来水疯狂安利!! DD这里也是收到好多用户提的宝贵建议!所以,连夜肝了波更新! 这次重点更新使用克隆音色进行A ...

  6. 6 MyBatis动态SQL之choose(when、otherwise)语句

    1 MyBatis动态SQL之if 语句 2 MyBatis动态sql之where标签|转 3 MyBatis动态SQL之set标签|转 4 MyBatis动态SQL之trim元素|转 5 MyBat ...

  7. CentOS 7 系统调优深度指南

    从内核参数.资源分配.存储性能到网络优化,覆盖全维度调优策略,并强调稳定性保障. 一.调优核心维度与操作命令 1. 内核参数调优 (/etc/sysctl.conf) bash # 编辑配置文件 vi ...

  8. Java安全_RCE漏洞

    [!NOTE] 本次学习使用开源项目: https://github.com/JoyChou93/java-sec-code/blob/master/src/main/java/org/joychou ...

  9. CRD的简单介绍

    介绍 Custom Resource Define 简称 CRD,是 Kubernetes(v1.7+)为提高可扩展性,让开发者去自定义资源的一种方式. CRD 资源可以动态注册到集群中,注册完毕后, ...

  10. Ant Design 的 a-input-number 组件限制最小值和最大值以及限制输入为数值型

    1.限制输入最大小值 <a-input-number v-model="form.deviceCpuThreshold" placeholder="请输入CPU阈值 ...