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

线程池ThreadPoolExecutor的拒绝策略

AbortPolicy

该策略是线程池的默认策略。使用该策略时,如果线程池队列满了丢掉这个任务并且抛出RejectedExecutionException异常。
源码如下:

    /**
     * A handler for rejected tasks that throws a
     * {@code RejectedExecutionException}.
     */
    public static class AbortPolicy implements RejectedExecutionHandler {
        /**
         * Creates an {@code AbortPolicy}.
         */
        public AbortPolicy() { }

        /**
         * Always throws RejectedExecutionException.
         *
         * @param r the runnable task requested to be executed
         * @param e the executor attempting to execute this task
         * @throws RejectedExecutionException always
         */
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            throw new RejectedExecutionException("Task " + r.toString() +
                                                 " rejected from " +
                                                 e.toString());
        }
    }

DiscardPolicy

这个策略和AbortPolicy的slient版本,如果线程池队列满了,会直接丢掉这个任务并且不会有任何异常。
源码如下:

    /**
     * A handler for rejected tasks that silently discards the
     * rejected task.
     */
    public static class DiscardPolicy implements RejectedExecutionHandler {
        /**
         * Creates a {@code DiscardPolicy}.
         */
        public DiscardPolicy() { }

        /**
         * Does nothing, which has the effect of discarding task r.
         *
         * @param r the runnable task requested to be executed
         * @param e the executor attempting to execute this task
         */
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
        }
    }

DiscardOldestPolicy

这个策略从字面上也很好理解,丢弃最老的。也就是说如果队列满了,会将最早进入队列的任务删掉腾出空间,再尝试加入队列。
因为队列是队尾进,队头出,所以队头元素是最老的,因此每次都是移除对头元素后再尝试入队。
源码如下:

/**
     * A handler for rejected tasks that discards the oldest unhandled
     * request and then retries {@code execute}, unless the executor
     * is shut down, in which case the task is discarded.
     */
    public static class DiscardOldestPolicy implements RejectedExecutionHandler {
        /**
         * Creates a {@code DiscardOldestPolicy} for the given executor.
         */
        public DiscardOldestPolicy() { }

        /**
         * Obtains and ignores the next task that the executor
         * would otherwise execute, if one is immediately available,
         * and then retries execution of task r, unless the executor
         * is shut down, in which case task r is instead discarded.
         *
         * @param r the runnable task requested to be executed
         * @param e the executor attempting to execute this task
         */
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            if (!e.isShutdown()) {
                e.getQueue().poll();
                e.execute(r);
            }
        }
    }

CallerRunsPolicy

使用此策略,如果添加到线程池失败,那么主线程会自己去执行该任务,不会等待线程池中的线程去执行。就像是个急脾气的人,我等不到别人来做这件事就干脆自己干。
源码如下:

    /**
     * A handler for rejected tasks that runs the rejected task
     * directly in the calling thread of the {@code execute} method,
     * unless the executor has been shut down, in which case the task
     * is discarded.
     */
    public static class CallerRunsPolicy implements RejectedExecutionHandler {
        /**
         * Creates a {@code CallerRunsPolicy}.
         */
        public CallerRunsPolicy() { }

        /**
         * Executes task r in the caller's thread, unless the executor
         * has been shut down, in which case the task is discarded.
         *
         * @param r the runnable task requested to be executed
         * @param e the executor attempting to execute this task
         */
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            if (!e.isShutdown()) {
                r.run();
            }
        }
    }

上述拒绝策略都是JDK提供的,是ThreadPoolExecutor的静态内部类。

自定义拒绝策略

实现RejectedExecutionHandler接口即可

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;

public class TestRejectedExecutionHandler implements RejectedExecutionHandler {
    @Override
    public void rejectedExecution(Runnable runnable, ThreadPoolExecutor executor) {
        System.out.println(Thread.currentThread().getName() + "----------------------------> 进入拒绝策略");

        // 延迟执行
        try {
            Thread.sleep(5L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 放入队列
        BlockingQueue<Runnable> workQueue = executor.getQueue();
        if (workQueue.offer(runnable)) {
            return;
        }

        // 新建线程执行
        new Thread(runnable, "【拒绝策略线程】").start();

        // OR
        // 放弃此任务,记录日志


    }
}

参考多线程 - ThreadPoolExecutor 常用的拒绝策略(RejectedExecutionHandler)

相关文章:

  • 关于 ScheduledThreadPoolExecutor 的一些资料汇总及个人理解
  • 无聊的事情真多
  • 转载一篇关于JNI实践的博客---以及编写自己的native方法
  • 竞标项目,何必这样呢?
  • 关于Netty的一点初步认识
  • 骨干跳槽让系统成鸡肋 IT主管如何是好
  • 关于 Unsafe 的一点认识与总结
  • Apache服务器虚拟主机设置技术深入解析
  • 转载文章:在Spring Boot中使用条件化的Bean
  • 《赢在用户》8月19日北京书友会报道!
  • kryo浅析
  • 六招彻底防范ARP病毒反复发作
  • 转载:面试前必须要知道的Redis面试题
  • 如何检测网内IP地址是否被占用
  • 转载:Java并发编程-原子类实现
  • 《Java8实战》-第四章读书笔记(引入流Stream)
  • Angular6错误 Service: No provider for Renderer2
  • Iterator 和 for...of 循环
  • JS 面试题总结
  • Python 反序列化安全问题(二)
  • Quartz初级教程
  • spring + angular 实现导出excel
  • Spring-boot 启动时碰到的错误
  • SSH 免密登录
  • Vue--数据传输
  • 百度小程序遇到的问题
  • 分享一个自己写的基于canvas的原生js图片爆炸插件
  • 精彩代码 vue.js
  • 悄悄地说一个bug
  • 小程序01:wepy框架整合iview webapp UI
  • 学习使用ExpressJS 4.0中的新Router
  • 3月7日云栖精选夜读 | RSA 2019安全大会:企业资产管理成行业新风向标,云上安全占绝对优势 ...
  • C# - 为值类型重定义相等性
  • HanLP分词命名实体提取详解
  • scrapy中间件源码分析及常用中间件大全
  • #LLM入门|Prompt#3.3_存储_Memory
  • $emit传递多个参数_PPC和MIPS指令集下二进制代码中函数参数个数的识别方法
  • (1/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
  • (10)ATF MMU转换表
  • (4)通过调用hadoop的java api实现本地文件上传到hadoop文件系统上
  • (Pytorch框架)神经网络输出维度调试,做出我们自己的网络来!!(详细教程~)
  • (zt)最盛行的警世狂言(爆笑)
  • (三) diretfbrc详解
  • (五)大数据实战——使用模板虚拟机实现hadoop集群虚拟机克隆及网络相关配置
  • (转) Face-Resources
  • (转)JVM内存分配 -Xms128m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=512m
  • (转)为C# Windows服务添加安装程序
  • (转载)PyTorch代码规范最佳实践和样式指南
  • .htaccess配置重写url引擎
  • .mysql secret在哪_MySQL如何使用索引
  • .net web项目 调用webService
  • .NET使用HttpClient以multipart/form-data形式post上传文件及其相关参数
  • .sdf和.msp文件读取
  • [ vulhub漏洞复现篇 ] Django SQL注入漏洞复现 CVE-2021-35042
  • [CentOs7]iptables防火墙安装与设置