【并发编程】- 线程池使用DiscardOldestPolicy策略、DiscardPolicy策略

当FutureTask遇上DiscardPolicy,有坑 今天来了解下当 FutureTask 遇上 DiscardPolicy 或 DiscardOldestPolicy 时容易掉的坑,然后分析分析问题产生的原因以及如何规避这类问题。 阅读详情

DiscardOldestPolicy策略

DiscardOldestPolicy策略是当任务添加到线程池中被拒绝时,线程池会放弃等待队列中最旧的未处理任务,将被拒绝的任务添加到等待队列中。
线程执行代码如下:

public class TheRunnable implements Runnable {

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    private String username;

    public TheRunnable(String username){
        super();
        this.username=username;
    }



    @Override
    public void run() {
        try {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
            System.out.println("线程名:"+username+"  开始时间:"+simpleDateFormat.format(new Date()));
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

运行类代码如下:

@Slf4j
public class DiscardOldestPolicyRun {
    public static void main(String[] args) {
        ArrayBlockingQueue arrayBlockingQueue = new ArrayBlockingQueue(2);
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 3, 10, TimeUnit.SECONDS, arrayBlockingQueue, new ThreadPoolExecutor.DiscardOldestPolicy());
        for (int i = 0; i < 5 ; i++) {
            TheRunnable runnable = new TheRunnable("Runnable " + i );
            threadPoolExecutor.execute(runnable);
        }
        try {
            Thread.sleep(500);
            Iterator iterator = arrayBlockingQueue.iterator();
            while (iterator.hasNext()){
                Object object = iterator.next();
                log.info("线程名:{}",((TheRunnable)object).getUsername());
            }
            threadPoolExecutor.execute(new TheRunnable("Runnable 6"));
            threadPoolExecutor.execute(new TheRunnable("Runnable 7"));
            iterator = arrayBlockingQueue.iterator();
            while(iterator.hasNext()){
                Object object = iterator.next();
                log.info("线程名:{}",((TheRunnable)object).getUsername());
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

运行结果如下:

线程名:Runnable 4 开始时间:16:47:54
线程名:Runnable 1 开始时间:16:47:54
线程名:Runnable 0 开始时间:16:47:54
16:47:55.509 [main] INFO com.ozx.concurrentprogram.executor.controller.DiscardOldestPolicyRun - 线程名:Runnable 2
16:47:55.516 [main] INFO com.ozx.concurrentprogram.executor.controller.DiscardOldestPolicyRun - 线程名:Runnable 3
16:47:55.517 [main] INFO com.ozx.concurrentprogram.executor.controller.DiscardOldestPolicyRun - 线程名:Runnable 6
16:47:55.517 [main] INFO com.ozx.concurrentprogram.executor.controller.DiscardOldestPolicyRun - 线程名:Runnable 7
线程名:Runnable 7 开始时间:16:47:56
线程名:Runnable 6 开始时间:16:47:56
从运行结果看出早期放入队列中两个任务被取消了,执行了后来添加的两个任务。

DiscardPolicy策略

DiscardPolicy策略是当任务添加到线程池中被拒绝时,线程池将丢弃被拒绝的任务。

运行类代码如下:

@Slf4j
public class DiscardPolicyRun {
    public static void main(String[] args) throws InterruptedException {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(5000);
                    log.info(Thread.currentThread().getName()+"执行结束");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };

        ArrayBlockingQueue arrayBlockingQueue = new ArrayBlockingQueue(2);
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 3, 10, TimeUnit.SECONDS, arrayBlockingQueue, new ThreadPoolExecutor.DiscardPolicy());
        for (int i = 0; i < 8 ; i++) {
            threadPoolExecutor.execute(runnable);
        }
        Thread.sleep(8000);
        log.info("线程池中最大线程数:{},队列数:{}",threadPoolExecutor.getPoolSize(),arrayBlockingQueue.size());
    }
}

运行结果如下:
17:40:14.301 [pool-1-thread-1] INFO com.ozx.concurrentprogram.executor.controller.DiscardPolicyRun - pool-1-thread-1执行结束
17:40:14.301 [pool-1-thread-2] INFO com.ozx.concurrentprogram.executor.controller.DiscardPolicyRun - pool-1-thread-2执行结束
17:40:14.301 [pool-1-thread-3] INFO com.ozx.concurrentprogram.executor.controller.DiscardPolicyRun - pool-1-thread-3执行结束
17:40:17.278 [main] INFO com.ozx.concurrentprogram.executor.controller.DiscardPolicyRun - 线程池中最大线程数:3,队列数:0
17:40:19.326 [pool-1-thread-1] INFO com.ozx.concurrentprogram.executor.controller.DiscardPolicyRun - pool-1-thread-1执行结束
17:40:19.326 [pool-1-thread-2] INFO com.ozx.concurrentprogram.executor.controller.DiscardPolicyRun - pool-1-thread-2执行结束
从运行结果看出多余的任务直接被取消执行。

线程池7:线程池拒绝任务的两个时机;线程池拒绝任务的四种策略简介(AbortPolicy,DiscardPolicy,DiscardOldestPolicy,CallerRunsPolicy;); 说明: (1)本篇博客主要介绍线程池拒绝任务的两个时机;线程池拒绝任务的四种策略; 目录 一:拒绝任务的时机; (1)当线程池关闭后,新来的任务就会被拒绝; (2)当线程池的最大线程数、队列容量都有接线,并且都满了;继续添加任务时就会拒绝; 二:拒绝的策略; (1)AbortPolicy策略; (2)DiscardPolicy策略; (3)DiscardOldestPolicy策略; (4)CallerRunsPolicy策略; 一:拒绝任务的时机; (1)当线程池关闭后,. 阅读详情

相关推荐

Java线程池的拒绝策略

拒绝策略被设置为CallerRunsPolicy,即当任务被拒绝时,由提交任务的线程来执行该任务。这是线程池默认的拒绝策略。在这个示例中,我们创建了一个线程池,并设置核心线程数为2,最大线程数为4,使用有界队列(大小为3)。DiscardOldestPolicy:当任务被拒绝时,丢弃队列中最老的一个任务,并尝试再次提交被拒绝的任务。,这意味着当线程池无法处理新的任务时,会丢弃队列中的最早的任务,并尝试将新的任务添加到队列中。,这意味着当线程池无法处理新的任务时,会默默地丢弃被拒绝的任务,不抛出任何异常。

2301_77350672的博客 2903

线称池饱和策略:DiscardOldestPolicy解释

前言 最近一直在线程池中游泳,对于四种的线称饱和策略,看了无数片优快云文章,居然发现一堆博主连个DiscardOldestPolicy 策略都说不清楚,每次都是一句话,丢弃线称队列的旧的任务,将新的任务添加,我也是无语?那 什么叫旧的任务? 怎么算是旧的任务??? DiscardOldestPolicy 解释 我们知道,线称饱和状态(拒绝策略)一共分为4种: ThreadPoolExecutor...

it佳佳的博客 1万+

EPLAN二次开发实战指南:从API接口到定制化界面

本文为EPLAN二次开发实战指南,详细介绍了从搭建C#开发环境、理解API接口到创建定制化插件的完整流程。通过实战案例,如批量修改设备属性和设计交互式界面,帮助电气工程师利用EPLAN二次开发实现工作流程自动化与深度定制,从而显著提升设计效率。

weixin_29246195的博客 806

线程池有哪 4 种拒绝策略?

第一种拒绝策略是 AbortPolicy,这种拒绝策略在拒绝任务时,会直接抛出一个类型为 RejectedExecutionException 的 RuntimeException,让你感知到任务被拒绝了,于是你便可以根据业务逻辑选择重试或者放弃提交等策略。 第二种拒绝策略是 DiscardPolicy,这种拒绝策略正如它的名字所描述的一样,当新任务被提交后直接被丢弃掉,也不会给你任何的通知,相对而言存在一定的风险,因为我们提交的时候根本不知道这个任务会被丢弃,可能造成数据丢失。 第三种拒绝策略是 Dis.

m0_45223880的博客 7205

搞定安卓11+抓包难题:用Kitsune Mask、magic_overlayfs和LSPosed三件套绕过SSL Pinning(保姆级教程)

本文详细解析了安卓11+系统中抓包面临的核心挑战,包括SSL Pinning和Root检测机制,并提供了使用Kitsune Mask、magic_overlayfs和LSPosed三件套的完整解决方案。通过动态分区技术解析和工具链配置,帮助开发者绕过安全限制,实现高效抓包分析。

weixin_42665255的博客 444

Windows下Colmap编译安装全攻略:从Boost到CUDA的避坑指南

本文详细介绍了在Windows系统下编译安装Colmap三维重建工具的完整流程与实战经验。针对Boost库版本兼容性、CUDA与Visual Studio的版本匹配等常见难题提供了具体的避坑指南和解决方案,帮助开发者高效完成从环境配置到最终部署的全过程。

weixin_28235513的博客 199

线程池的拒绝策略解析

当线程池的任务队列已满并且线程数量达到最大限制时,新提交的任务就需要一种处理方式,这就是拒绝策略。不同的拒绝策略决定了在这种情况下如何应对新任务,比如是直接丢弃新任务、抛出异常还是其他处理方式。Java 中的线程池()提供了几种内置的拒绝策略,这些策略都在等相关类中实现。

m0_57836225的博客 710

基于OpenCV的围棋终局识别与胜负判定系统实现

计算机视觉是人工智能领域的关键技术,它使计算机能够从数字图像或视频中获取、处理和分析信息。其核心原理在于通过图像处理算法提取特征,并基于这些特征进行识别、分类和测量。在工程实践中,计算机视觉技术为自动化、智能化应用提供了强大支持,广泛应用于工业检测、自动驾驶、医疗影像分析等领域。本文聚焦于一个具体的应用场景:利用OpenCV库实现围棋终局识别。通过图像预处理、棋盘检测与透视校正、交叉点定位等步骤,结合围棋规则逻辑,构建了一套从棋盘图像自动判定胜负的解决方案。该方案涉及自适应二值化、霍夫变换、连通域分析等关键

weixin_29100927的博客 280

ThreadPoolExecutor饱和策略

饱和策略(Saturation Policy),也称为拒绝策略(Rejection Policy),是指当线程池中的线程数已达到最大值且任务队列已满时,如何处理新提交的任务。此时,线程池无法再接受新的任务,因此需要一种策略来决定如何处理这些任务。除了内置的几种饱和策略,Java 还允许开发者自定义接口来实现特定的饱和策略。@Override// 这里可以实现自定义的处理逻辑,如记录日志、重试任务等特点自定义饱和策略可以完全根据业务需求定制化,满足特殊的并发场景需求。

Flying_Fish_roe的博客 1532

GPU架构-SIMT

本文深度剖析了GPU的SIMT架构,从硬件实现层面解析其与SIMD的本质差异。SIMT通过将32个线程捆绑为warp执行,在标量编程模型下实现数据并行。文章对比了SIMD和SIMT的执行模型、分支处理机制及存储层次,指出SIMT是对SIMD的虚拟化抽象。重点分析了Volta架构引入的独立线程调度技术,以及访存合并对性能的关键影响。通过定量数据展示了各代GPU架构的寄存器文件规模和线程调度机制,为开发者优化GPU程序提供了硬件层面的理论基础。

技术引领业务创新 974

BIOS更新后PIN不可用怎么办?从原理到实操的完整修复指南

在计算机维护中,BIOS更新是常见的固件升级操作,但其引发的登录异常却常让用户措手不及。Windows Hello PIN并非传统密码,它通过TPM芯片与设备启动环境(PCR状态)强绑定,一旦主板固件或安全启动配置改变,TPM便会拒绝释放密钥,导致“由于此设备上的更改,你的PIN不再可用”。理解这一原理后,恢复路径清晰可控:优先尝试密码登录,或通过WinRE替换utilman.exe创建临时管理员,必要时还需处理BitLocker恢复密钥。本文面向系统维护与数据安全场景,系统梳理PIN失效的恢复流程与避坑方

weixin_31364787的博客 377

thread.abort java_Java线程池的拒绝策略

一、简介jdk1.5 版本新增了JUC并发编程包,极大的简化了传统的多线程开发。前面文章中介绍了线程池的使用,链接地址:https://www.cnblogs.com/eric-fang/p/9004020.htmlJava线程池,是典型的池化思想的产物,类似的还有数据库的连接池、redis的连接池等。池化思想,就是在初始的时候去申请资源,创建一批可使用的连接,这样在使用的时候,就不必再进行创建连...

weixin_42310267的博客 207

遥感目标检测数据集汇总

文章目录1. 光学数据集1.1 DIOR1.2 LEVIR1.3 DOTA1.4 RSOD1.5 NWPU VHR-101.6 VEDAI1.7 COWC1.8 ITCVD1.9 DIUx xView 20181.10 HRSC20161.11 TAS1.12 SZTAKI‐INRIA1.13 UCAS AOD1.14 DLR 3K Vehicle2. SAR2.1 SSDD2.2 SSDD+2....

quanwei的博客 6万+

为什么需要线程池?

核心线程数 = CPU核数 + 1。核心线程数 = CPU核数 * 2。

xzdH4y3Pr的博客 199

将MathType、zotero嵌入Word、WPS

最近也是慢慢学起了写文稿之类的内容,在写论文的时候,肯定会遇到一些数学公式的插入,如果使用wps、word等自带的插入公式,一般不符合投稿期刊的格式要求,而且不方便、不美观,故开始研究MathType 这款插入公式的工具。

2401_83617940的博客 2277

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Java进阶13 线程池

ThreadPoolExecutor类。

2601_95052718的博客 164

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

线程池那点事

Executor ### 执行已提交 Runnable任务的对象,执行器;只有一个方法 void execute(Runnable command); ExecutorService ### extends Executor ### shutdown(),不接受新的任务,执行还没有执行完的任务 ### shutdownNow(),理解结束,不处理还没执行完的任务 A...

独立开发者 149

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

【JUC】ThreadPoolExecutor构造函数及拒绝策略

JUC ThreadPoolExecutor 构造 构造函数 拒绝 策略 拒绝策略

fofcn的专栏 211

一文读懂 Java 线程池拒绝策略:从原理到实践(含 CallerRunsPolicy 等 4 种策略全解析)

在 Java 并发编程中,线程池是控制线程数量、提升资源利用率的核心组件。但当线程池的任务队列满了、且已达到最大线程数时,新提交的任务会被拒绝 —— 这时候就需要拒绝策略来决定如何处理这些被拒绝的任务。         今天我们就来详细拆解 Java 线程池的 4 种内置拒绝策略,包括大家常问的CallerRunsPolicy,以及默认的AbortPolicy、“静默丢弃” 的DiscardPolicy、“丢弃 oldest” 的DiscardOldestPolicy,帮你搞懂每种策略的适用场景和实践用法

lijingxiaov5的博客 1697

【Java并发编程实战】Java中线程池的拒绝策略详解

直接抛出 RejectedExecutionException。丢弃队列中最老的任务,尝试执行新任务。不想丢失任务,可以接受调用线程执行。允许丢弃旧任务,保证新任务及时处理。AbortPolicy(默认)直接丢弃新任务,不抛异常。需要明确知道任务被拒绝。

gaochufukanyongren的博客 122

深入理解Java并发编程中的线程池拒绝策略及其应用场景

除了使用内置策略,开发者可以通过实现`RejectedExecutionHandler`接口来定义自己的拒绝策略,以满足特定业务需求。例如,在一个需要保证关键任务绝对不丢失的系统中,可以自定义一个策略,将被拒绝的任务持久化到数据库或磁盘中,待系统负载下降后再重新提交执行(这通常与任务队列相结合)。另一种常见的自定义策略是实现带有超时机制的重试逻辑,在任务被拒绝后等待一段时间再尝试提交,直到成功或超过最大重试次数。自定义策略赋予了开发者最大的灵活性来处理复杂的业务边界情况。

SPM613110的博客 445

(JUC)线程池的四种拒绝策略

策略行为描述使用场景抛异常必须保证任务执行调用线程执行任务限流,避免抛异常直接丢弃任务任务可丢失丢弃最旧任务,再提交新任务老任务可舍弃,优先新任务执行💡 Tips:如果任务不可丢失,通常使用 AbortPolicy 或 CallerRunsPolicy。如果任务可以舍弃,DiscardPolicy 或 DiscardOldestPolicy 可以减少系统压力。

savemeill的博客 510

线程池的拒绝策略

转载自链接 static是Java中的一个关键字,我们不能声明普通外层类或者包为静态的。static用于下面四种情况。 1.静态变量:我们可以将类级别的变量声明为static。静态变量是属于类的,而不是属于类创建的对象或实例。因为静态变量被类的所有实例共用,所以非线程安全的。通常静态变量还和关键字final一起用,作为所有对象共用的资源或常量。如果静态变量不是私有的,那么可以通过ClassName.variableName来访问它. ...

王其的博客 1703

14多线程02 线程池 原子性 并发工具类

1.线程池 1.1 线程状态介绍 当线程被创建并启动以后,它既不是一启动就进入了执行状态,也不是一直处于执行状态。线程对象在不同的时期有不同的状态。那么Java中的线程存在哪几种状态呢?Java中的线程 状态被定义在了java.lang.Thread.State枚举类中,State枚举类的源码如下: public class Thread { public enum State { /* 新建 */ NEW , /* 可运行状态

InLoadwetrust的博客 193
上一篇: IDEA 新建 JavaWeb 项目(:找不到 Web Application 解决方法)
下一篇: 你有了解过这些架构设计,架构知识体系吗?(架构书籍推荐)
Java技术那些事儿
博客等级 码龄5年 2306粉丝 2584原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值