线程池-拒绝策略

news2024/11/15 11:51:53

线程池-拒绝策略

    • RejectedExecutionHandler
      • AbortPolicy
      • CallerRunsPolicy
      • DiscardPolicy
      • DiscardOldestPolicy
      • 自定义拒绝策略

核心线程已用尽 & 阻塞队列已满 & 超过最大线程数时,再向线程池提交任务,则会触发线程池的拒绝策略。

RejectedExecutionHandler

拒绝策略是由 RejectedExecutionHandler 接口定义的。

Java 默认提供了四种拒绝策略。

AbortPolicy

中止测试。这也线程池默认的拒绝策略。当线程池无法接受一个新的任务时,会抛出一个 RejectedExecutionException 异常。这种策略会导致任务出现丢失,且会出现抛异常的特殊情况。

image-20240714004714703

// 创建一个核心线程10个 最大线程10个 阻塞队列1个线程池
    public static final ThreadPoolExecutor THREAD_POOL_EXECUTOR =
            new ThreadPoolExecutor(10,
                    10,
                    60,
                    TimeUnit.SECONDS,
                    new ArrayBlockingQueue<>(1),
                    Executors.defaultThreadFactory(),
                    new ThreadPoolExecutor.AbortPolicy()
            );

    public static void main(String[] args) {
        int errorSize = 0;
        for (int i = 0; i < 20; i++) {
            final int finalI = i;
            THREAD_POOL_EXECUTOR.execute(() -> {
                Thread thread = Thread.currentThread();
                String name = thread.getName();
                System.out.println("name:" + name + "-" + +System.currentTimeMillis() + " Start-index-" + finalI);
                try {
                    TimeUnit.SECONDS.sleep(3);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("name:" + name + "-" + System.currentTimeMillis() + " End");
            });
        }
    }

这里可以看见只有11个任务( 10 核心线程在执行,1 个在等待队列中,这个时候线程池就不能接受任务了 )执行成功了,当接受12个任务的时候,这个时候抛出了 RejectedExecutionHandler 因为没有 try-catch 所以线程中断,后续的循环也不会走了。

image-20240714010854094

for 循环中加上try-catch,可以捕获到异常了,那么后续的 12-20 个任务也可以提交到线程池中,但依然会被执行拒绝策略。

public static void main(String[] args) {
        int errorSize = 0;
        for (int i = 0; i < 20; i++) {
            try {
                final int finalI = i;
                THREAD_POOL_EXECUTOR.execute(() -> {
                    Thread thread = Thread.currentThread();
                    String name = thread.getName();
                    System.out.println("name:" + name + "-" + +System.currentTimeMillis() + " Start-index-" + finalI);
                    try {
                        TimeUnit.SECONDS.sleep(3);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    System.out.println("name:" + name + "-" + System.currentTimeMillis() + " End");
                });
            }catch (RejectedExecutionException e){
                e.printStackTrace();
            }
        }
    }

CallerRunsPolicy

当任务被拒绝时,线程池会让提交任务的线程来执行这个任务。这样可以确保任务不丢失,但会让提交任务的这个线程压力很大,阻塞时间会很久。

image-20240714004740735

// 将拒绝策略修改为后。
new ThreadPoolExecutor.CallerRunsPolicy()

这里可以看见是 main 线程去帮我们执行了这个任务。在现在的这个情况下main线程要执行slepp(3) 9 次,会大大的降低 main 线程的执行效率

image-20240714004049916

DiscardPolicy

丢弃任务。在线程池无法接受新任务的时候,则会执行将这个丢失掉,跳过执行。使用场景需要对任务丢失有极大的容忍度。

image-20240714004936413

// 将拒绝策略修改为后。
new ThreadPoolExecutor.DiscardPolicy()

只允许了 11 个任务,后续的 9 个全部丢失。

image-20240714005510519

DiscardOldestPolicy

丢弃最旧任务。当线程池无法接收新的任务时,线程池会将阻塞队列中等待时间最久的任务给丢掉到,将新的任务加入到阻塞队中。也就是将阻塞队列头部的任务出队,再将新任务入队。这样做的目的是牺牲最老的任务以容纳最新的任务。

image-20240714005845400

// 将拒绝策略修改为后。
new ThreadPoolExecutor.DiscardOldestPolicy()

执行了 11 个任务,前 10 个与最后一个。这是因为 12-19 个都被拒绝策略给丢弃掉不执行了。

image-20240714010005438

自定义拒绝策略

当 Java 提供的这四个拒绝策略你觉得不好用时,你可以自己定义这个拒绝策略来处理。也就是提供 RejectedExecutionHandler 接口的实现即可。

public static final ThreadPoolExecutor THREAD_POOL_EXECUTOR =
            new ThreadPoolExecutor(10,
                    10,
                    60,
                    TimeUnit.SECONDS,
                    new ArrayBlockingQueue<>(1),
                    Executors.defaultThreadFactory(),
                    // 使用当发生拒绝策略的时候使用forkJoinPool这个线程来执行任务
                    new RejectedExecutionHandler() {
                        @Override
                        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                            ForkJoinPool.commonPool().execute(r);
                        }
                    }
            );

10 个被THREAD_POOL_EXECUTOR执行,10 个被forkJoinPool执行。

image-20240714010423309

当然这里不建议使用 ForkJoinPool 这种方式来处理,当大量任务会被执行拒绝策略的时候,这会导致ForkJoinPool的线程池无线扩充,最终导致内存异常等问题。这里只是举例慎用!!!!
…(img-jERM8ZpL-1720890569610)]

当然这里不建议使用 ForkJoinPool 这种方式来处理,当大量任务会被执行拒绝策略的时候,这会导致ForkJoinPool的线程池无线扩充,最终导致内存异常等问题。这里只是举例慎用!!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1924546.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

35 解决单条链路故障问题-华三链路聚合

InLoopBack接口是一种虚拟接口。InLoopBack接口由系统自动创建&#xff0c;用户不能进行配置和删除&#xff0c;但是可以显示&#xff0c;其物理层和链路层协议永远处于up状态。InLoopBack接口主要用于配合实现报文的路由和转发&#xff0c;任何送到InLoopBack接口的IP报文都会…

Linux系统编程之基础I/O

一、C文件接口 1、hello.c写文件 #include <stdio.h> #include <string.h>int main() {FILE *fp fopen("myfile", "w");if(!fp){printf("fopen error!\n");}const char *msg "hello bit!\n";int count 5;while(count-…

LabVIEW学习-LabVIEW储存Excel表格

上述实现了将格式化的时间和正弦波的频率振幅相位以及正弦波数据输入到excel表格中。 下面介绍其中使用到的函数&#xff1a; 1. 所在位置&#xff0c;函数选板->定时->获取日期/时间(秒) 2. 将获取的时间进行格式化处理&#xff0c;输出格式化的日期/时间字符串。 函…

通过Bugly上报的日志查找崩溃闪退原因

第一步&#xff0c;解析堆栈信息 在bugly上收集到的信息是这样的 0x000000010542e46c 0x0000000104db4000 6792300 OS应用发生崩溃时&#xff0c;系统会生成一份崩溃日志&#xff0c;这份日志中包含了崩溃时的堆栈信息&#xff0c;但这些堆栈信息并非直接指向源代码&#x…

C# Winform布局控件的几种方式

在 C# WinForms 应用程序中&#xff0c;布局控件和布局管理器可以帮助开发者创建响应式的用户界面&#xff0c;即使在窗口大小改变时也能保持控件的正确位置和尺寸。 通常我们采用Panel和Dock&#xff0c;辅助Anchor实现类似如下的布局。 以下是几种常见的布局控件和方法&…

实用机器学习(快速入门)

前言 因为需要机器学习的助力&#xff0c;所以&#xff08;浅浅&#xff09;进修了一下。现在什么东西和AI结合一下感觉就好发文章了&#xff1b;我看了好多学习视频&#xff0c;发现机器学习实际上是数学&#xff0c;并不是常规的去学习代码什么的&#xff08;虽然代码也很简…

技术周总结 2024.07.08~07.14(算法,Python,Java,Scala,PHP)

文章目录 一、07.13 周六1.0&#xff09;算法题&#xff1a;字符串中的单词反转1.1&#xff09; 问题01:可靠性计算中的MTTR MTTF MTBF 分别指什么&#xff1f;他们之间有什么联系&#xff1f;MTTR (Mean Time to Repair)MTTF (Mean Time to Failure)MTBF (Mean Time Between F…

解决:Failed to load PostCSS config: Failed to load PostCSS config

报错信息&#xff1a; [Failed to load PostCSS config: Failed to load PostCSS config (searchPath: D:/project/vite-vue-project): [Error] Must use import to load ES Module: D:\project\vite-vue-project\postcss.config.ts require() of ES modules is not supported…

从零编写一个神经网络完成手写数字的识别分类(pytorch实现)

1. 前言 很多人都有这样的困惑&#xff1a; “我已经看过很多有关神经网络的书和视频了&#xff0c;但为什么感觉还是似懂非懂呢&#xff1f;” 那是因为&#xff0c;你从来都没有完整的、从头编写并训练过一个神经网络 学习AI相关的算法&#xff0c;尤其是深度学习方向&…

【原创】springboot+mysql小区疫情防控网站设计与实现

个人主页&#xff1a;程序猿小小杨 个人简介&#xff1a;从事开发多年&#xff0c;Java、Php、Python、前端开发均有涉猎 博客内容&#xff1a;Java项目实战、项目演示、技术分享 文末有作者名片&#xff0c;希望和大家一起共同进步&#xff0c;你只管努力&#xff0c;剩下的交…

搭建hadoop+spark完全分布式集群环境

目录 一、集群规划 二、更改主机名 三、建立主机名和ip的映射 四、关闭防火墙(master,slave1,slave2) 五、配置ssh免密码登录 六、安装JDK 七、hadoop之hdfs安装与配置 1)解压Hadoop 2)修改hadoop-env.sh 3)修改 core-site.xml 4)修改hdfs-site.xml 5) 修改s…

2、ASPX、.NAT(环境/框架)安全

ASPX、.NAT&#xff08;环境/框架&#xff09;安全 源自小迪安全b站公开课 1、搭建组合&#xff1a; WindowsIISaspxsqlserver .NAT基于windows C开发的框架/环境 对抗Java xx.dll <> xx.jar 关键源码封装在dll文件内。 2、.NAT配置调试-信息泄露 功能点&#xf…

Docker 容器内的php 安装redis扩展

1、https://pecl.php.net/package/redis 下载redis扩展 2、解压redis扩展包&#xff0c;然后通过命令拷贝到php容器 docker cp ~/nginx/redis-4.3.0/* myphp-fpm:/usr/src/php/ext/redis/ myphp-fpm是你的php容器 &#xff5e;/nginx/redis**** 是redi扩展包路径 3、进入php容…

jenkins系列-09.jpom构建java docker harbor

本地先启动jpom server agent: /Users/jelex/Documents/work/jpom-2.10.40/server-2.10.40-release/bin jelexjelexxudeMacBook-Pro bin % sh Server.sh start/Users/jelex/Documents/work/jpom-2.10.40/agent-2.10.40-release/bin jelexjelexxudeMacBook-Pro bin % ./Agent.…

单元测试实施最佳方案(背景、实施、覆盖率统计)

1. 什么是单元测试&#xff1f; 对于很多开发人员来说&#xff0c;单元测试一定不陌生 单元测试是白盒测试的一种形式&#xff0c;它的目标是测试软件的最小单元——函数、方法或类。单元测试的主要目的是验证代码的正确性&#xff0c;以确保每个单元按照预期执行。单元测试通…

mysql-联合查询

一.联合查询的概念 .对于unio查询,就是把多次查询的结果合并起来,形成一个新的查询果集。 SELECT 字段列表 FROM 表A... UNION[ALL] SELECT 字段列表 FROM 表B...&#xff0c; 二.将薪资低于5000的员工,和年龄大于50岁的员工全部查询出来 select * from emp where salary&…

Vulnhub靶场 | DC系列 - DC2

目录 环境搭建渗透测试 环境搭建 靶机镜像下载地址&#xff1a;https://vulnhub.com/entry/dc-2,311/需要将靶机和 kali 攻击机放在同一个局域网里&#xff1b;本实验kali 的 IP 地址&#xff1a;192.168.10.146。 渗透测试 使用 nmap 扫描 192.168.10.0/24 网段存活主机 …

window下安装go环境

一、go官网下载安装包 官网地址如下&#xff1a;https://golang.google.cn/dl/ 选择对应系统的安装包&#xff0c;这里是window系统&#xff0c;可以选择zip包&#xff0c;下载完解压就可以使用 二、配置环境变量 这里的截图配置以win11为例 我的文件解压目录是 D:\Software…

【进阶篇-Day9:JAVA中单列集合Collection、List、ArrayList、LinkedList的介绍】

目录 1、集合的介绍1.1 概念1.2 集合的分类 2、单列集合&#xff1a;Collection2.1 Collection的使用2.2 集合的通用遍历方式2.2.1 迭代器遍历&#xff1a;&#xff08;1&#xff09;例子&#xff1a;&#xff08;2&#xff09;迭代器遍历的原理&#xff1a;&#xff08;3&…

Halcon机器视觉15种缺陷检测案例_2不均匀表面刮伤检测

2&#xff1a; 不均匀表面刮伤检测 思路 1、获取图像 2、分割图像 3、处理区域 4、获取大&#xff0c;小缺陷 效果 原图 代码 *02 不均匀表面刮伤检测 dev_update_off () dev_close_window ()*****************第一步 获取图像******************* read_image (Image, 2.不…