java线程池使用小技巧:自定义拒绝策略
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线程池使用小技巧:自定义拒绝策略的更多相关文章
- 线程池ThreadPoolExecutor里面4种拒绝策略
ThreadPoolExecutor类实现了ExecutorService接口和Executor接口,可以设置线程池corePoolSize,最大线程池大小,AliveTime,拒绝策略等.常用构造方 ...
- Java线程池实现原理之自定义线程池(一)
1.队列的概念 谈到多线程先讲下队列的概念,之后的多线程学习会用到此类知识. 队列分为:阻塞式队列(有界).非阻塞式队列(无界),遵循着先进先出.后进后出的原则.阻塞队列与非阻塞队列区别: 1.非阻塞 ...
- JUC之线程池的实现原理以及拒绝策略
线程池实现原理 向线程池提交任务后,线程池如何来处理这个任务,之前我们了解了7个参数,我们通过这些参数来串联其线程池的实现原理. 1.在创建了线程池后,开始等待请求 2.当调用execute()方法添 ...
- java线程池(newSingleThreadExecutor())小应用
创建单个线程,用来操作一个无界的队列任务,不会使用额外的线程.如果线程崩溃会重新创建一个,直到任务完成. 代码: import java.util.concurrent.ExecutorService ...
- 按照阿里巴巴规范创建Java线程池
前言 Executors Executors 是一个Java中的工具类.提供工厂方法来创建不同类型的线程池. 常用方法: 1.newSingleThreadExecutor 介绍:创建一个单线程的 ...
- Java 线程池原理分析
1.简介 线程池可以简单看做是一组线程的集合,通过使用线程池,我们可以方便的复用线程,避免了频繁创建和销毁线程所带来的开销.在应用上,线程池可应用在后端相关服务中.比如 Web 服务器,数据库服务器等 ...
- SpringBoot线程池和Java线程池的实现原理
使用默认的线程池 方式一:通过@Async注解调用 public class AsyncTest { @Async public void async(String name) throws Inte ...
- 一个基于Java线程池管理的开源框架Hippo4j实践
@ 目录 概述 定义 线程池痛点 功能 框架概览 架构 部署 Docker安装 二进制安装 运行模式 依赖配置中心 接入流程 个性化配置 线程池监控 无中间件依赖 接入流程 服务端配置 三方框架线程池 ...
- 深入理解Java线程池:ScheduledThreadPoolExecutor
介绍 自JDK1.5开始,JDK提供了ScheduledThreadPoolExecutor类来支持周期性任务的调度.在这之前的实现需要依靠Timer和TimerTask或者其它第三方工具来完成.但T ...
- java 线程池第一篇 之 ThreadPoolExcutor
一:什么是线程池? java 线程池是将大量的线程集中管理的类,包括对线程的创建,资源的管理,线程生命周期的管理.当系统中存在大量的异步任务的时候就考虑使用java线程池管理所有的线程.减少系统资源的 ...
随机推荐
- Spring基于注解的事务管理
Spring基于注解的事务管理 源码 代码测试 pom.xml <?xml version="1.0" encoding="UTF-8"?> < ...
- 通过SpringBoot配置文件配置Druid数据源
目录 引入坐标依赖 配置application.properties文件 新建一个controller观察使用的是哪一个数据源 在SpringBoot 1.X 中,spring-boot-starte ...
- 代码随想录第十六天 | Leecode 513. 找树左下角的值、112. 路径总和、113. 路径总和 II、106. 从中序与后序遍历序列构造二叉树
Leecode 513. 找树左下角的值 题目描述 给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值. 假设二叉树中至少有一个节点. 示例 1: 输入: root = [ ...
- 【记录】Excel 2021|(三)VBA使用Selenium自动登录网页
文章目录 1 安装 Selenium Basic 2 下载webdriver 3 自动登录 1 安装 Selenium Basic 首先需要安装Selenium Basic,才能在工具栏中找到Sele ...
- git-fame实战操作
参考网址:https://pydigger.com/pypi/git-fame,https://github.com/casperdcl/git-fame Git-fame 简介: Pretty-pr ...
- SQL 日常练习 (二十)
也只是尽快搬完这快一个月 sql 的砖, 准备要来整新学习模块了, 因此, 正好趁着五一, 加波速. 也会一直坚守和追求, 学无止境, 气有浩然. 每次都会说, 这是一种精神的传承,而我想的是, 不仅 ...
- LangChain4j如何自定义文档转换器实现数据清洗?
LangChain4j 提供了 3 种 RAG(Retrieval-Augmented Generation,检索增强生成)实现,我们通常在原生或高级的 RAG 实现中,要对数据进行清洗,也就是将外接 ...
- 详解ES6升级优化以及知识点汇总
@charset "UTF-8"; .markdown-body { line-height: 1.75; font-weight: 400; font-size: 15px; o ...
- DOS命令——带包的类的编译与运行
手动版:a.javac编译当前类文件 b.手动建立与包名对应的文件夹 c.把a步骤中编译出的.class 文件放到b步骤中的最底层文件夹下 ...
- 【公众号搬运】React-Native开发鸿蒙NEXT
.markdown-body { line-height: 1.75; font-weight: 400; font-size: 16px; overflow-x: hidden; color: rg ...