java ThreadPoolExecutor 线程池

优点

ThreadPoolExecutor 提供了强大的灵活性和自定义参数的能力,可以根据实际需求来灵活配置线程池的行为。

位置

        java.util.concurrent 包下

构造函数

public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue)public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory)public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler)\public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)

核心参数

corePoolSize:线程池的基本大小,即使没有任务执行时也保持存活的线程数。
maximumPoolSize:线程池所能容纳的最大线程数(包括核心线程)。
keepAliveTime:非核心线程空闲等待新任务的最长时间,在这个时间内如果没有新任务提交,那么非核心线程将会被终止。
unit:与keepAliveTime搭配使用的单位,如TimeUnit.SECONDS或TimeUnit.MILLISECONDS等。
workQueue:任务队列,用于保存待处理的任务,可以是无界队列(例如LinkedBlockingQueue)或有界队列(例如ArrayBlockingQueue)。
threadFactory:创建新线程的工厂,默认使用Executors.defaultThreadFactory(),也可以自定义来设置线程名称、优先级等属性。
handler:拒绝策略,当线程池和工作队列都已满,无法接收新的任务时,会调用此策略进行处理。AbortPolicy(直接抛出异常);CallerRunsPolicy(由调用者线程自己执行任务);DiscardPolicy(直接丢弃新任务);DiscardOldestPolicy(丢弃队列中最旧的任务并尝试提交当前任务)。

线程池工作流程

当一个任务提交到ThreadPoolExecutor时:
如果当前运行的线程数量小于corePoolSize,则创建一个新的线程来执行任务。
若当前线程数等于corePoolSize但小于maximumPoolSize,且工作队列已满,则创建新的线程来执行任务。
如果线程数已经达到maximumPoolSize并且工作队列也满了,则根据RejectedExecutionHandler策略处理该任务。

线程池状态

线程池具有五种状态:RUNNING、SHUTDOWN、STOP、TIDYING 和 TERMINATED。
状态转换通常发生在调用诸如shutdown(), shutdownNow(), 或者所有任务完成后

重要方法

shutdown():线程池不再接受新的任务,但会继续处理已经提交的任务。
shutdownNow():尝试停止所有正在执行的任务,并返回尚未开始执行的任务列表。
execute(Runnable command):提交一个Runnable任务给线程池执行。
submit(Callable<T> task):提交一个Callable任务,能够返回结果。
awaitTermination(long timeout, TimeUnit unit):阻塞当前线程,直到线程池关闭或者超时发生。
isTerminated():检查线程

示例

        示例1:

package org.springblade.test;import lombok.extern.slf4j.Slf4j;import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;@Slf4j
public class Test {@org.junit.jupiter.api.Testpublic void ThreadPoolExecutorExample() {// 自定义线程工厂ThreadFactory namedThreadFactory = new NamedThreadFactory();// 创建有界任务队列BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(10);// 定义拒绝策略RejectedExecutionHandler handler = new ThreadPoolExecutor.CallerRunsPolicy();// 创建线程池ThreadPoolExecutor executor = new ThreadPoolExecutor(2, // 核心线程数4, // 最大线程数60L, // 空闲线程存活时间(单位:秒)TimeUnit.SECONDS, // 时间单位workQueue, // 工作队列namedThreadFactory, // 线程工厂handler // 拒绝策略);// 提交任务到线程池for (int i = 0; i < 20; i++) {final int taskId = i;Runnable worker = new Runnable() {@Overridepublic void run() {System.out.println("Task " + taskId + " is running by " + Thread.currentThread().getName());try {Thread.sleep(500); // 模拟耗时操作} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Task " + taskId + " finished");}};executor.execute(worker);}// 关闭线程池executor.shutdown();while (!executor.isTerminated()) {// 等待所有任务执行完毕}System.out.println("所有任务已完成,线程池已关闭");}
}/*** 定义线程创建逻辑,设置线程名称前缀等*/
class NamedThreadFactory implements ThreadFactory {private static final AtomicInteger poolNumber = new AtomicInteger(1);private final ThreadGroup group;private final AtomicInteger threadNumber = new AtomicInteger(1);private final String namePrefix;NamedThreadFactory() {SecurityManager s = System.getSecurityManager();group = (s != null) ? s.getThreadGroup() :Thread.currentThread().getThreadGroup();namePrefix = "MyTaskPool-" + poolNumber.getAndIncrement() + "-thread-";}@Overridepublic Thread newThread(Runnable r) {Thread t = new Thread(group, r,namePrefix + threadNumber.getAndIncrement(),0);if (t.isDaemon())t.setDaemon(false);if (t.getPriority() != Thread.NORM_PRIORITY)t.setPriority(Thread.NORM_PRIORITY);return t;}
}
//我们提交了20个任务到线程池。由于工作队列容量有限(10),当队列满后会尝试增加线程直到达到最大线程数(4)。
//如果在达到最大线程数后仍有新的任务提交,将根据指定的拒绝策略处理这些任务。
// 在本例中,我们选择了 CallerRunsPolicy,这意味着超出线程池处理能力的任务将会由调用者线程(主线程)直接执行。
//执行结果
//Task 0 is running by MyTaskPool-1-thread-1
// Task 14 is running by main
// Task 1 is running by MyTaskPool-1-thread-2
// Task 13 is running by MyTaskPool-1-thread-4
// Task 12 is running by MyTaskPool-1-thread-3
// Task 12 finished
// Task 1 finished
// Task 0 finished
// Task 13 finished
// Task 14 finished
// Task 4 is running by MyTaskPool-1-thread-3
// Task 19 is running by main
// Task 5 is running by MyTaskPool-1-thread-4
// Task 3 is running by MyTaskPool-1-thread-1
// Task 2 is running by MyTaskPool-1-thread-2
// Task 5 finished
// Task 4 finished
// Task 19 finished
// Task 3 finished
// Task 8 is running by MyTaskPool-1-thread-1
// Task 2 finished
// Task 9 is running by MyTaskPool-1-thread-2
// Task 7 is running by MyTaskPool-1-thread-3
// Task 6 is running by MyTaskPool-1-thread-4
// Task 8 finished
// Task 10 is running by MyTaskPool-1-thread-1
// Task 6 finished
// Task 9 finished
// Task 7 finished
// Task 15 is running by MyTaskPool-1-thread-2
// Task 11 is running by MyTaskPool-1-thread-4
// Task 16 is running by MyTaskPool-1-thread-3
// Task 10 finished
// Task 17 is running by MyTaskPool-1-thread-1
// Task 11 finished
// Task 15 finished
// Task 16 finished
// Task 18 is running by MyTaskPool-1-thread-4
// Task 17 finished
// Task 18 finished
// 所有任务已完成,线程池已关闭

        示例2:

package org.springblade.test;import lombok.extern.slf4j.Slf4j;import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;@Slf4j
public class Test {@org.junit.jupiter.api.Testpublic void ThreadPoolExecutorExample() {// 定义核心线程数、最大线程数、空闲线程存活时间以及时间单位int corePoolSize = 5;int maximumPoolSize = 10;long keepAliveTime = 60; // 60秒TimeUnit unit = TimeUnit.SECONDS;// 创建一个有界的LinkedBlockingQueue作为任务队列,容量为20BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(20);// 创建线程池ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize,maximumPoolSize,keepAliveTime,unit,workQueue);// 提交任务到线程池for (int i = 0; i < 30; i++) {final int taskId = i;Runnable worker = () -> {System.out.println("Task " + taskId + " is running by " + Thread.currentThread().getName());try {Thread.sleep(1000); // 模拟耗时操作} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Task " + taskId + " finished");};executor.execute(worker);}// 关闭线程池(这里没有立即关闭,而是等待所有任务执行完毕)executor.shutdown();while (!executor.isTerminated()) {// 等待所有任务执行完毕}System.out.println("所有任务已完成,线程池已关闭");}
}//执行结果
// Task 0 is running by pool-1-thread-1
// Task 1 is running by pool-1-thread-2
// Task 3 is running by pool-1-thread-4
// Task 2 is running by pool-1-thread-3
// Task 4 is running by pool-1-thread-5
// Task 25 is running by pool-1-thread-6
// Task 26 is running by pool-1-thread-7
// Task 27 is running by pool-1-thread-8
// Task 29 is running by pool-1-thread-10
// Task 28 is running by pool-1-thread-9
// Task 2 finished
// Task 0 finished
// Task 3 finished
// Task 5 is running by pool-1-thread-1
// Task 6 is running by pool-1-thread-4
// Task 7 is running by pool-1-thread-3
// Task 1 finished
// Task 8 is running by pool-1-thread-2
// Task 4 finished
// Task 9 is running by pool-1-thread-5
// Task 25 finished
// Task 10 is running by pool-1-thread-6
// Task 27 finished
// Task 28 finished
// Task 26 finished
// Task 13 is running by pool-1-thread-7
// Task 29 finished
// Task 14 is running by pool-1-thread-10
// Task 11 is running by pool-1-thread-8
// Task 12 is running by pool-1-thread-9
// Task 7 finished
// Task 15 is running by pool-1-thread-3
// Task 5 finished
// Task 16 is running by pool-1-thread-1
// Task 6 finished
// Task 17 is running by pool-1-thread-4
// Task 8 finished
// Task 18 is running by pool-1-thread-2
// Task 9 finished
// Task 19 is running by pool-1-thread-5
// Task 10 finished
// Task 20 is running by pool-1-thread-6
// Task 12 finished
// Task 21 is running by pool-1-thread-9
// Task 14 finished
// Task 11 finished
// Task 22 is running by pool-1-thread-8
// Task 23 is running by pool-1-thread-10
// Task 13 finished
// Task 24 is running by pool-1-thread-7
// Task 15 finished
// Task 17 finished
// Task 16 finished
// Task 18 finished
// Task 19 finished
// Task 20 finished
// Task 23 finished
// Task 22 finished
// Task 24 finished
// Task 21 finished

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

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

相关文章

进程与线程:通过实际生活来解析计算机的基本运作单位

进程与线程 进程与线程&#xff1a;详细解析计算机的基本运作单位1. 进程&#xff1a;独立的执行环境1.1 进程的特点&#xff1a; 2. 线程&#xff1a;轻量级的执行单元2.1 线程的特点&#xff1a; 3. 区别和联系4. 表格 进程与线程&#xff1a;详细解析计算机的基本运作单位 在…

Unity铰链四杆机构设计和运动仿真

一、效果图 设定好各边长度和转速后&#xff0c;点击【设置并启动】&#xff0c;自动生成一个机构模型&#xff0c;并按照原理进行运转 二、铰链四杆机构介绍 机架&#xff1a;A和D是固定位置&#xff0c;叫做机架。 曲柄&#xff1a;B点绕A点旋转&#xff0c;构成曲柄。 连…

990-22产品经理:The benefits of business analytics 业务分析的优势

Turning data into pound isn’t just something for big corporations now. Thanks to relatively inexpensive software and easy-to-use, drag-and-drop tools, pulling data and analysing it – with the goal of growing your business – has never been more uncomplic…

英语学习资源分享

键盘侠的单词记忆软件&#xff1a; Qwerty Learner — 为键盘工作者设计的单词与肌肉记忆锻炼软件https://qwerty.kaiyi.cool/ 经济学人、纽约客等英语外刊杂志下载&#xff1a;若github无法进入可以试试下载VPN插件&#xff08;在浏览器中安装免费的VPN插件&#xff0c;个人推…

重拾C++之菜鸟刷算法第4篇---哈希表

一些理论知识 哈希函数是一种映射关系&#xff0c;根据关键词key&#xff0c;经过一定函数关系得到元素的位置。 常见的哈希函数构造方法 直接定址法 除留余数法 叠加法 随机数法 哈希冲突 不同关键字通过相同哈希函数计算出相同的哈希地址&#xff0c;该种现象称为哈希…

视频汇聚/存储/压缩/诊断平台EasyCVR视频联网整合方案应用特点

随着科技的不断发展&#xff0c;监控视频在各个领域的应用越来越广泛。为了更好地管理和利用这些视频资源&#xff0c;视频联网与整合的需求也越来越多。通过视频联网技术将不同地理位置或不同设备的视频资源进行整合&#xff0c;实现实时共享和集中管理。视频联网整合方案的应…

6、云原生安全之falco的规则解读(部分)(下)

文章目录 3、规则解析记录3.21、检测是否有非特权用户成功执行userfaultfd系统调用3.22、监控容器内通过curl/wget的下载行为3.23、检测容器内修改release_agent文件的场景(无论修改成功与否)3.24、检测Java进程通过网络加载class类文件的行为,该规则用于检测log4j的应急3.2…

Linux运维_Bash脚本_编译安装GNU-Tools

Linux运维_Bash脚本_编译安装GNU-Tools Bash (Bourne Again Shell) 是一个解释器&#xff0c;负责处理 Unix 系统命令行上的命令。它是由 Brian Fox 编写的免费软件&#xff0c;并于 1989 年发布的免费软件&#xff0c;作为 Sh (Bourne Shell) 的替代品。 您可以在 Linux 和 …

2024最新算法:鹦鹉优化算法(Parrot optimizer,PO)求解23个基准函数

一、鹦鹉优化算法 鹦鹉优化算法&#xff08;Parrot optimizer&#xff0c;PO&#xff09;由Junbo Lian等人于2024年提出的一种高效的元启发式算法&#xff0c;该算法从驯养的鹦鹉中观察到的觅食、停留、交流和对陌生人行为的恐惧中汲取灵感。这些行为被封装在四个不同的公式中…

C++_红黑树

目录 1、红黑树的规则 2、红黑树节点的定义 3、红黑树插入节点的调整操作 3.1 情况一 3.2 情况二 3.3 情况三 4、红黑树的实现 结语 前言&#xff1a; 在C中&#xff0c;红黑树是二叉搜索树的另一种优化版本&#xff0c;他与AVL树的区别在于保持树的平衡方式不同&…

【Mysql】Navicat数据库勿删了mysql.infoschema@localhost,导致打不开数据库,如何修改

运行报错如下&#xff1a; 1449 . The user specified as a definer (mysql.infoschemaocalhost) does not exist该方法不需要重启mysql&#xff0c;或者重装&#xff1b;仅需要恢复删除的mysql.infoschemalocalhost用户 一、登录建立用户 mysql -uroot -pxxxxxx密码二、建立…

【网上商城系统的设计与开发】

目录 1.实训概况 1 1.1 实训题目 1 1.2实训时间 1 1.3实训目的 1 1.4 实训环境 1 1.5 实训内容 2 1.6 进度安排 3 2.需求分析 5 2.1 功能需求分析 5 2.1.1用户需求分析 5 2.2.2网站前台需求 5 2.2.3网站后台需求 6 2.2 可行性分析 7 2.2.1社会可行性 7 2.2.2技术可行性 8 3.系统…

Sora学习(一):Sora技术路径整体认知

前文&#xff1a;最近跟着DataWhale组队学习这一期“Sora原理与技术实战”&#xff0c;本篇博客主要是基于DataWhale成员、厦门大学平潭研究院杨知铮研究员分享的Sora技术原理详解课件内容以及参考网上一些博客资料整理而来&#xff08;详见文末参考文献&#xff09;&#xff0…

【谈一谈】并发编程_锁的分类

【谈一谈】并发编程_锁的分类 Hello!~大家好!~每天进步一点点,日复一日,我们终将问剑顶峰 这里主要是介绍下我们常用的锁可以分为几类,目的是整体框架作用~方便后续的并发文章 说白了,这篇就是开头哈~ 本文总纲: 一.可重入锁和不可重入锁 我们开发中一般用到的都是可重入锁比如…

Photoshop 2023:重塑创意,引领数字艺术新纪元

在数字艺术的浩瀚星空中&#xff0c;Adobe Photoshop 2023&#xff08;简称PS 2023&#xff09;如同一颗璀璨的新星&#xff0c;为Mac和Windows用户带来了前所未有的创意体验。这款强大的图像处理软件不仅继承了前作的精髓&#xff0c;更在细节上进行了诸多创新&#xff0c;让每…

运行Python文件时出现‘utf-8’code can‘t decode byte 如何解决?(如图)

如图 亦或者出现“SyntaxError: Non-UTF-8 code starting with \xbb ” 出现这种问题往往是编码格式导致的&#xff0c;我们可以在py文件中的第一行加入以下代码&#xff1a; # codingutf-8或者 # codinggdk优先使用gbk编码 解释一下常用的两种编码格式&#xff1a; utf-…

朱维群将出席用碳不排碳碳中和顶层科技路线设计开发

演讲嘉宾&#xff1a;朱维群 演讲题目&#xff1a;“用碳不排碳”碳中和顶层科技路线设计开发 简介 姓名&#xff1a;朱维群 性别&#xff1a;男 出生日期&#xff1a;1961-09-09 职称&#xff1a;教授 1998年毕业于大连理工大学精细化工国家重点实验室精细化工专业&…

什么是B+树,和B树有什么不同?

&#x1f449;博主介绍&#xff1a; 博主从事应用安全和大数据领域&#xff0c;有8年研发经验&#xff0c;5年面试官经验&#xff0c;Java技术专家&#xff0c;WEB架构师&#xff0c;阿里云专家博主&#xff0c;华为云云享专家&#xff0c;51CTO 专家博主 ⛪️ 个人社区&#x…

Spring Initializer环境问题

1.基于jdk8与本地 环境准备 1)下载jdk8并安装 2&#xff09;下载maven 3.6.3并解压放入D盘maven目录下&#xff0c;去掉外层 设置阿里源 打开settings.xml,在mirrors标签之内增加&#xff0c;注意粘贴后</id>中的/有可能被删掉&#xff0c;要自己补上 <mirror>&l…

健身房预约小程序制作详细步骤解析

如果你是一位健身爱好者&#xff0c;或者是一位健身教练&#xff0c;你一定知道预约健身的痛苦。传统的预约方式不仅麻烦&#xff0c;而且效率低下。但是&#xff0c;现在&#xff0c;我们可以使用一种神仙工具——乔拓云网&#xff0c;来搭建一个属于自己的健身预约小程序&…