线程池高手进阶:揭秘ThreadPoolExecutor的小妙招!

news2024/12/23 18:50:47

线程池高手进阶:揭秘ThreadPoolExecutor的小妙招! - 程序员古德

RejectedExecutionHandler总结

ThreadPoolExecutor 是 Java 中用于创建和管理线程池的接口,当线程池中的任务队列已满,并且线程池中的线程数量已经达到最大时,如果再有新的任务提交,就需要一个策略来处理这些无法执行的任务。它 提供了四种拒绝策略,都是 RejectedExecutionHandler 接口的实现,如下:

  1. AbortPolicy(默认策略):直接抛出一个 RejectedExecutionException 异常。
  2. CallerRunsPolicy:调用执行任务的 execute 方法的线程来运行任务,如果执行程序已经关闭,那么任务将被抛弃。
  3. DiscardPolicy:无法执行的任务将被抛弃,不会抛出任何异常。
  4. DiscardOldestPolicy:如果执行程序尚未关闭,则位于工作队列头部的任务将被删除,然后重试执行任务(如果再次失败,则重复此过程)。

以下是使用ThreadPoolExecutor的代码示例,如下:

import java.util.concurrent.*;  
  
public class ThreadPoolExecutorDemo {  
    public static void main(String[] args) {  
        // 创建一个固定大小的线程池  
        int corePoolSize = 2;  
        int maximumPoolSize = 4;  
        long keepAliveTime = 10L;  
        TimeUnit unit = TimeUnit.SECONDS;  
        BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(2);  
  
        // 使用不同的拒绝策略  
        RejectedExecutionHandler abortPolicy = new ThreadPoolExecutor.AbortPolicy();  
        RejectedExecutionHandler callerRunsPolicy = new ThreadPoolExecutor.CallerRunsPolicy();  
        RejectedExecutionHandler discardPolicy = new ThreadPoolExecutor.DiscardPolicy();  
        RejectedExecutionHandler discardOldestPolicy = new ThreadPoolExecutor.DiscardOldestPolicy();  
  
        // 创建线程池并设置拒绝策略  
        ThreadPoolExecutor executor1 = new ThreadPoolExecutor(  
                corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, abortPolicy);  
  
        ThreadPoolExecutor executor2 = new ThreadPoolExecutor(  
                corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, callerRunsPolicy);  
  
        ThreadPoolExecutor executor3 = new ThreadPoolExecutor(  
                corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, discardPolicy);  
  
        ThreadPoolExecutor executor4 = new ThreadPoolExecutor(  
                corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, discardOldestPolicy);  
  
        // 提交任务  
        for (int i = 0; i < 10; i++) {  
            final int taskId = i;  
            executor1.execute(() -> System.out.println("Executing task " + taskId + " with AbortPolicy"));  
            executor2.execute(() -> System.out.println("Executing task " + taskId + " with CallerRunsPolicy"));  
            executor3.execute(() -> System.out.println("Executing task " + taskId + " with DiscardPolicy"));  
            executor4.execute(() -> System.out.println("Executing task " + taskId + " with DiscardOldestPolicy"));  
        }  
  
    }  
}

在上面的代码示例中,由于工作队列和线程池的大小都设置得很小,所以提交的任务会很快填满队列和线程池,从而触发拒绝策略,不同的拒绝策略适用于不同的场景,在实际应用中,应该根据具体需求来合理设置线程池的大小、工作队列的容量以及拒绝策略。

ThreadFactory总结

ThreadFactory接口常用于在ThreadPoolExecutor中管理控制线程的名称、优先级、是否守护线程以及其他线程属性。下面是一个简单的ThreadFactory使用案例,案例中定义了一个CustomThreadFactory类,如下代码:

import java.util.concurrent.ThreadFactory;  
import java.util.concurrent.atomic.AtomicInteger;  
  
public class CustomThreadFactory implements ThreadFactory {  
    private final String prefix;  
    private final AtomicInteger threadNumber = new AtomicInteger(1);  
  
    public CustomThreadFactory(String prefix) {  
        this.prefix = prefix;  
    }  
  
    @Override  
    public Thread newThread(Runnable r) {  
        // 创建一个新线程  
        Thread thread = new Thread(r);  
        // 设置线程名称,使用前缀和递增的数字  
        thread.setName(prefix + "-" + threadNumber.getAndIncrement());  
        // 可以设置其他属性,比如优先级、守护状态等  
        // thread.setPriority(Thread.MAX_PRIORITY);  
        // thread.setDaemon(false);  
        return thread;  
    }  
}

在上面代码中:

  1. CustomThreadFactory类实现了ThreadFactory接口,并重写了newThread方法。
  2. 构造函数接受一个prefix参数,用于生成线程名称的前缀。
  3. 使用AtomicInteger来生成唯一的线程编号,确保在多线程环境下编号不会重复。
  4. newThread方法中,创建一个新的Thread对象,并通过setName方法设置线程的名称,这里使用前缀和递增的编号来构建线程名称,方便在日志或调试时识别线程。
  5. 还可以根据需要调用其他Thread方法来设置线程的优先级、守护状态等属性。

如下是CustomThreadFactory的使用方法,如下:

import java.util.concurrent.ThreadPoolExecutor;  
import java.util.concurrent.TimeUnit;  
import java.util.concurrent.SynchronousQueue;  
  
public class ThreadPoolExample {  
    public static void main(String[] args) {  
        // 创建一个具有自定义线程工厂的线程池  
        ThreadPoolExecutor executor = new ThreadPoolExecutor(  
            5, // corePoolSize  
            10, // maximumPoolSize  
            60L, // keepAliveTime  
            TimeUnit.SECONDS, // unit for keepAliveTime  
            new SynchronousQueue<>(), // workQueue  
            new CustomThreadFactory("CustomThreadPool-") // 自定义线程工厂  
        );  
  
        // 提交任务给线程池  
        for (int i = 0; i < 20; i++) {  
            final int taskId = i;  
            executor.submit(() -> {  
                // 执行任务  
                System.out.println("Task " + taskId + " is running on thread " + Thread.currentThread().getName());  
            });  
        }  
  
        // 关闭线程池(这通常是在应用程序关闭时完成的)  
        // executor.shutdown();  
    }  
}

关注我,每天学习互联网编程技术 - 程序员古德

END!

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

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

相关文章

c++ 截图GetWindowDC,并保存到文件夹下---手把手教

工作中遇到一个需求&#xff0c;需要在用户操作过后&#xff0c;需要截图来确认用户操作过后&#xff0c;真实的呈现结果&#xff0c;用来后期验证 直接上代码 直接使用&#xff0c;修改自己需要捕获的窗口名字就可以了 OnBnClickedBtUpimage(){CString strPathTmp;GetAppPath…

2024年 IT 行业就业情况能否回春?很多人说道…

我只能说可以&#xff0c;以前我是看不到的。但是鸿蒙全栈自研让我重新看到希望&#xff01; 2024年1月18日&#xff0c;华为鸿蒙千帆启航发布会。讲到HarmonyOS NEXT作为原生鸿蒙&#xff0c;其系统底座全栈自研&#xff0c;去掉了传统的AOSP 代码&#xff08;“Android 开放…

基于变异混合蛙跳算法的车间调度最优化matlab仿真,可以任意调整工件数和机器数,输出甘特图

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 4.1 车间调度问题&#xff08;JSSP&#xff09;描述 4.2 蛙跳算法&#xff08;SFLA&#xff09;基本原理 4.2.1 初始化 4.2.2 局部搜索 4.2.3 全局信息交换 4.2.4 变异策略 4.2.5 终止…

音乐证书通过率发布,市场对持有者需求旺盛

音乐证书的考试难度备受关注&#xff0c;通过率终于揭晓。据官方公布的数据&#xff0c;该证书的通过率相对较低&#xff0c;需要考生在音乐技能和表现方面有出色的表现。然而&#xff0c;持有音乐证书的人才在市场上需求旺盛&#xff0c;各种音乐机构和企业对其表现出强烈兴趣…

【AI视野·今日CV 计算机视觉论文速览 第288期】Thu, 11 Jan 2024

AI视野今日CS.CV 计算机视觉论文速览 Thu, 11 Jan 2024 Totally 50 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computer Vision Papers Towards Online Sign Language Recognition and Translation Authors Ronglai Zuo, Fangyun Wei, Brian Mak手语识别的目标…

MyBatis详解(2)-- mybatis配置文件

MyBatis详解&#xff08;2&#xff09; mybatis配置文件 mybatis配置文件 1.构建SqlSessionFactory的依据。 2.MyBatis最为核心的内容&#xff0c;对MyBatis的使用影响很大。 3.配置文件的层次顺序不能颠倒&#xff0c;一旦颠倒会出现异常。 < c o n f i g u r a t i o n…

【原创】linux为什么不是实时操作系统

文章目录 一、什么是实时操作系统&#xff08;RTOS&#xff09;&#xff1f;二、linux为什么不是实时操作系统&#xff1f;中断响应时间中断处理时间任务调度时间1、No Forced Preemption(Server)2、Voluntary Kernel Preemption(Desktop)3、Preemptible Kernel(Low-Latency De…

windows 下docker-compose 试玩 paperlsess

第一步安装&#xff1a;&#xff08;假设docker-compose已安装好&#xff09; 下载 docker-compose.yml &#xff0c;docker-compose.env: github下载地址 在docker-paperless.env增加环境变量,设置管理员账户信息&#xff1a; PAPERLESS_ADMIN_USER: admin PAPERLESS_ADMIN_P…

什么品牌洗地机最好?专业旗舰级洗地机推荐

作为一个打工族&#xff0c;很能理解大家对日常清洁繁琐的烦恼&#xff0c;尤其是在忙碌工作后难以有力气打扫卫生。这时候&#xff0c;洗地机就是解决问题的利器了。它不仅方便轻松&#xff0c;还能有效消菌杀毒&#xff0c;助力深度清洁。若你正在为选择哪款洗地机而烦恼&…

当软件开发具备了低代码的开发能力,难以想象会有多“香”

一、前言 低代码开发平台&#xff0c;一个号称能在几分钟的时间里开发出一套公司内部都可使用的应用系统开发工具。 很多人或许都隐隐听说过低代码&#xff0c;因为低代码不仅远名国外&#xff0c;国内的腾讯、阿里、华为、网易、百度等科技巨头也纷纷入局。 那么市面上都有哪些…

【复现】万户ezoffice协同管理平台 SQL注入漏洞_26

目录 一.概述 二 .漏洞影响 三.漏洞复现 1. 漏洞一&#xff1a; 四.修复建议&#xff1a; 五. 搜索语法&#xff1a; 六.免责声明 一.概述 万户ezOFFICE协同管理平台分为企业版和政务版。 解决方案由五大应用、两个支撑平台组成&#xff0c;分别为知识管理、工作流程、沟…

1.8 万 Star!这款 Nginx 可视化配置工具太强了

NginxConfig简介 Nginx Config 是一个强大的 Nginx 配置文件生成器&#xff0c;号称配置 Nginx 服务器所需的唯一工具。 正因为 Nginx 功能强大&#xff0c;所以针对其各个功能的配置项会显得特别多&#xff0c;对于我们来说要记住那么多配置是一件十分头疼的事&#xff0c;甚…

Python环境下基于机器学习的NASA涡轮风扇发动机剩余使用寿命RUL预测

本例所用的数据集为C-MAPSS数据集&#xff0c;C-MAPSS数据集是美国NASA发布的涡轮风扇发动机数据集&#xff0c;其中包含不同工作条件和故障模式下涡轮风扇发动机多源性能的退化数据&#xff0c;共有 4 个子数据集&#xff0c;每个子集又可分为训练集、 测试集和RUL标签。其中&…

【Java并发】聊聊Future如何提升商品查询速度

java中可以通过new thread、实现runnable来进行实现线程。但是唯一的缺点是没有返回值、以及抛出异常&#xff0c;而callable就可以解决这个问题。通过配合使用futuretask来进行使用。 并且Future提供了对任务的操作&#xff0c;取消&#xff0c;查询是否完成&#xff0c;获取结…

XPath常用定位方式

1、通常定位元素有比较固定的八种定位方式&#xff0c;如下图&#xff1b; 2、平时可以通过浏览器右键进行获取定位方式&#xff0c;但是通常获取的元素无法准确定位或者太长这时就需要自己通过XPath语法来进行定位&#xff1b;目前我这边记录两种常用的定位方式&#xff0c;第…

【大数据】流处理基础概念(二):时间语义(处理时间、事件时间、水位线)

流处理基础概念&#xff08;一&#xff09;&#xff1a;Dataflow 编程基础、并行流处理流处理基础概念&#xff08;二&#xff09;&#xff1a;时间语义&#xff08;处理时间、事件时间、水位线&#xff09;流处理基础概念&#xff08;三&#xff09;&#xff1a;状态和一致性模…

10. Profile

1. 区分环境的配置 1.1. properties 配置 假设&#xff0c;一个应用的工作环境有&#xff1a;dev、test、prod 那么&#xff0c;我们可以添加 4 个配置文件&#xff1a; applcation.properties - 公共配置application-dev.properties - 开发环境配置application-test.proper…

电脑文件mfc140.dll丢失的解决方法指导,怎么快速修复mfc140.dll

mfc140.dll 文件的缺失是个普遍的问题&#xff0c;在日常使用中可能会时不时遇到。本文主要目的是详细介绍一旦遇到 mfc140.dll 文件缺失&#xff0c;应该如何进行下载和安装的步骤。不再赘言&#xff0c;下面就一起深入了解mfc140.dll丢失的解决方法指导。 一. mfc140.dll的作…

跟着pink老师前端入门教程-day09

二十二、定位 22.1 为什么需要定位 1. 某个元素可以自由的在一个盒子内移动位置&#xff0c;并且压住其他盒子 2. 当我们滚动窗口时&#xff0c;盒子是固定屏幕某个位置的 解决方法&#xff1a; 1. 浮动可以让多个块级盒子一行没有缝隙排列显示&#xff0c;经常用于横向排…

Spring Boot开发Spring Security

这里我对springboot不做过多描述&#xff0c;因为我觉得学这个的肯定掌握了springboot这些基础 导入核心依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring‐boot‐starter‐security</artifactId> </depen…