ScheduledThreadPoolExecutor 及 ThreadPoolExecutor的基本使用及说明

关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。
专注于分享各领域原创系列文章 ,擅长java后端、移动开发、人工智能等,希望大家多多支持。

目录

  • 一、导读
  • 二、概览
    • 2.1 为什么不推荐使用Executors去创建线程池
  • 三、使用
    • 3.1 ThreadPoolExecutor
    • 3.2 ScheduledThreadPoolExecutor
      • 3.2.1 通过构造方法创建
      • 3.2.2 通过Executors工厂方法创建
      • 3.2.3 ScheduledThreadPoolExecutor与ThreadPoolExecutor异同
  • 四、 推荐阅读

ddd

一、导读

我们继续总结学习Java基础知识,温故知新。

本文讲述 ScheduledThreadPoolExecutor 及 ThreadPoolExecutor。

二、概览

我们并不推荐使用Executors去创建线程池,为了更好地控制和管理线程池,通过ThreadPoolExecutor或者ScheduledThreadPoolExecutor的方式去创建线程池。这两种方式可以根据具体的需求设置线程池的参数,例如核心线程数、最大线程数、队列类型等,以及自定义拒绝策略来处理任务无法执行的情况。

2.1 为什么不推荐使用Executors去创建线程池

newFixedThreadPool(固定线程数)
newSingleThreadExecutor(单线程)
主要问题是堆积的请求处理队列可能会耗费非常大的内存,甚至OOM。线程数固定,任务多了之后容易堆积。

newCachedThreadPool(可缓存的线程池)
newScheduledThreadPool(定时执行的线程池)
主要问题是线程数最大数是Integer.MAX_VALUE,可能会创建数量非常多的线程,甚至OOM。不限定线程多数量,任务一多,容易创建无限多线程。

三、使用

在这里插入图片描述

3.1 ThreadPoolExecutor

public class ThreadPoolDemo {private static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2,   // 核心线程数10,  // 最大线程数10L, // 线程 存活时间TimeUnit.SECONDS,  // 线程存活时间单位new LinkedBlockingQueue(100));// 缓冲队列public static void main(String[] args) {threadPoolExecutor.execute(new Runnable() {@Overridepublic void run() {}});}
}

构造方法

public ThreadPoolExecutor(// 线程池核心线程数int corePoolSize, // 线程池最大数int maximumPoolSize, // 空闲线程存活时间long keepAliveTime,  // 时间单位TimeUnit unit,// 线程池所使用的缓冲队列BlockingQueue<Runnable> workQueue,// 线程池创建线程使用的工厂ThreadFactory threadFactory,// 线程池对拒绝任务的处理策略RejectedExecutionHandler handler)

处理任务的优先级为核心线程corePoolSize、任务队列workQueue、最大线程maximumPoolSize,如果三者都满了,使用handler处理被拒绝的任务。

3.2 ScheduledThreadPoolExecutor

ScheduledThreadPoolExecutor 是 Java 8 引入的一个新特性,继承自ThreadPoolExecutor。
它们都提供了一些基本的线程池操作,如 execute() 方法用于执行任务,schedule() 方法用于延迟定时执行任务。
不同之处在于 ScheduledThreadPoolExecutor 可以根据指定的周期和时间间隔来调度任务执行,从而实现周期性执行任务的效果。

ScheduledThreadPoolExecutor用于替代Timer,比Timer更强大,更灵活,Timer对应的是单个后台线程,而ScheduledThreadPoolExecutor可以在构造函数中指定多个对应的后台线程数。

ScheduledThreadPoolExecutor 内部构造了两个内部类 ScheduledFutureTask 和 DelayedWorkQueue,基于这两个类实现。

有两种创建方式:

3.2.1 通过构造方法创建

new ScheduledThreadPoolExecutor(int corePoolSize, // 核心线程数ThreadFactory threadFactory, //主要作用是用来捕获异常和设置线程名称RejectedExecutionHandler handler) //拒绝策略ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
executor.execute(...);
executor.shutdown(...);
executor.schedule(...);
executor.scheduleAtFixedRate(...);
executor.scheduleWithFixedDelay(...);
executor.submit(...);

3.2.2 通过Executors工厂方法创建

方式一:
newSingleThreadScheduledExecutor() 只有一个工作线程的线程池。如果内部工作线程由于执行周期任务异常而被终止,则会新建一个线程替代它的位置。方式二:
Executors.newScheduledThreadPool(int corePoolSize, ThreadFactory threadFactory)ScheduledExecutorService service = Executors.newScheduledThreadPool(1);service.execute(...);
service.shutdown(...);
service.schedule(...);
service.scheduleAtFixedRate(...);
service.scheduleWithFixedDelay(...);
service.submit(...);

我们常用的方法有以下一些


/**创建并执行在给定延迟后启用的一次性操作* @param command 执行的任务* @param delay 延迟的时间* @param unit 延迟的时间单位*/
schedule(Runnable command, long delay, TimeUnit unit)周期任务,在第一次执行完之后延迟delay后开始下一次执行,重点是任务执行完后才开始下一次。
如果任务执行过程抛出异常,不会再执行该任务!
/**定时执行 周期任务,在initialDelay后开始调度该任务,任务执行完成后,延迟 delay 时间再次执行* @param command 执行的任务* @param initialDelay 初始延迟的时间* @param delay 延迟的时间* @param unit 延迟的时间单位*/
scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)周期任务,第一次执行延期时间为initialDelay,之后每隔period执行一次
如果任务执行过程抛出异常,不会再执行该任务!
/**按照固定的评率定时执行周期任务,不受任务运行时间影响。在initialDelay后开始调度该任务,然后 delay 时间后再次执行如果任务执行的时间比period长的话,会导致该任务延迟执行,不会同时执行* @param command 执行的任务* @param initialDelay 初始延迟的时间* @param period 延迟的时间* @param unit 延迟的时间单位*/
scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)

ScheduledThreadPoolExecutor 有两个关闭策略:

  1. 关闭策略 1:在任务队列为空时,调用 shutdown() 方法关闭线程池。
  2. 关闭策略 2:当线程池中的所有任务都执行完毕时,调用 shutdown() 方法关闭线程池。

这两个关闭策略的区别在于,当线程池中的任务队列为空时,调用 shutdown() 方法关闭线程池可以立即关闭线程池,避免了等待任务执行完毕的时间开销。而当线程池中的任务都执行完毕时,调用 shutdown() 方法关闭线程池则无法立即关闭线程池,需要等待所有任务执行完毕后才能关闭线程池。

其他的比较简单,就不列出来。

使用 ScheduledThreadPoolExecutor 时一定要注意异常处理, 如果使用不当,会导致定时任务不再执行。

3.2.3 ScheduledThreadPoolExecutor与ThreadPoolExecutor异同

  1. ThreadPoolExecutor 是一个普通的线程池实现,用于执行提交的任务。它不提供定时调度任务的功能。而ScheduledThreadPoolExecutor 是ThreadPoolExecutor的子类,它扩展了线程池的功能,可以执行延迟任务和定时任务。
  2. ThreadPoolExecutor 是基于工作队列的线程池,它使用工作队列来保存需要执行的任务,并通过线程池中的工作线程来执行这些任务。ScheduledThreadPoolExecutor 在ThreadPoolExecutor的基础上添加了一个调度器,用于管理延迟任务和定时任务的执行。
  3. ThreadPoolExecutor 默认情况下是懒汉式创建线程,即在需要执行任务时才创建线程;而ScheduledThreadPoolExecutor 在初始化时就会一次性创建指定数量的线程,这些线程会一直存在,用于执行被调度的任务。

四、 推荐阅读

Java 专栏

SQL 专栏

数据结构与算法

Android学习专栏

在这里插入图片描述

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

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

相关文章

C++ list底层实现原理

文章目录 一、list底层实现二、类构成三、构造函数四、迭代器五、获取第一个元素六、获取最后一个元素七、插入元素 一句话&#xff1a;list底层实现一个双向循环链表 一、list底层实现 一个双向循环链表 二、类构成 class list : protected_List_base_list_base.lsit_impl…

python进阶书籍的推荐 知乎,python入门后如何进阶

本篇文章给大家谈谈python进阶书籍的推荐 知乎&#xff0c;以及python入门后如何进阶&#xff0c;希望对各位有所帮助&#xff0c;不要忘了收藏本站喔。 1、Python应该怎么学_python应该怎么学 想要学习Python&#xff0c;需要掌握的内容还是比较多的&#xff0c;对于自学的同…

【MySQL】索引特性

​&#x1f320; 作者&#xff1a;阿亮joy. &#x1f386;专栏&#xff1a;《零基础入门MySQL》 &#x1f387; 座右铭&#xff1a;每个优秀的人都有一段沉默的时光&#xff0c;那段时光是付出了很多努力却得不到结果的日子&#xff0c;我们把它叫做扎根 目录 &#x1f449;没…

重大更新|Sui主网即将上线流动性质押,助力资产再流通

Sui社区一直提议官方上线流动质押功能&#xff0c;现在通过SIP过程&#xff0c;已经升级该协议以实现这一功能。 Sui使用委托权益证明机制&#xff08;DPoS&#xff09;来选择和奖励负责运营网络的验证节点。为了保障网络安全&#xff0c;验证节点通过质押SUI token获得质押奖…

抖音短视频矩阵系统源码:SEO优化开发解析

抖音短视频矩阵系统源码是一个基于抖音短视频平台的应用程序。它允许用户上传和观看短视频&#xff0c;以及与其他用户交互。SEO优化开发解析是指对该系统进行搜索引擎优化的开发解析。 一、 在进行SEO优化开发解析时&#xff0c;可以考虑以下几点&#xff1a; 关键词优化&…

Java Stream流

Java 8 版本新增的Stream&#xff0c;配合同版本出现的Lambda &#xff0c;给我们操作集合&#xff08;Collection&#xff09;提供了极大的便利。Stream流是JDK8新增的成员&#xff0c;允许以声明性方式处理数据集合&#xff0c;可以把Stream流看作是遍历数据集合的一个高级迭…

linux 系统编程

C标准函数与系统函数的区别 什么是系统调用 由操作系统实现并提供给外部应用程序的编程接口。(Application Programming Interface&#xff0c;API)。是应用程序同系统之间数据交互的桥梁。 一个helloworld如何打印到屏幕。 每一个FILE文件流&#xff08;标准C库函数&#xff…

前端调用合约如何避免出现transaction fail

前言&#xff1a; 作为开发&#xff0c;你一定经历过调用合约的时候发现 gas fee 超出限制&#xff0c;但是不知道报了什么错。这个时候一般都是触发了require错误合约校验。对于用户来说他不理解为什么一笔交易会花费如此大的gas&#xff0c;那我们作为开发如何尽量避免这种情…

Jvm的一些技巧

反编译字节码文件 找到对应的class文件所在的目录&#xff0c;使用javap -v -p 命令 查询运行中某个Java进程的Jvm参数 【案例】查询 MethodAreaDemo 这个类运行过程中&#xff0c;初始的元空间大小 MetaspaceSize jps 查询 Java 进程的进程ID ![在这里插入图片描述](https…

新零售行业如何做会员管理和会员营销

蚓链数字化营销系统全渠道会员管理解决方案&#xff0c;线上线下统一管理&#xff0c;打造私域流量&#xff0c;微信、门店会员全渠道管理&#xff0c;打通私域流量池&#xff0c;实现裂变营销&#xff1a; 开启新零售之路&#xff0c;必然要摒弃原有的管理模式&#xff0c;大…

C# NDArray System.IO.FileLoadException报错原因分析

C# NDArray System.IO.FileLoadException 报错原因分析&#xff1a; 1.NuGet程序包版本有冲突 2.统一项目版本 1.打开解决方案NuGet程序包设置 2.查看是否有版本冲突 3.统一版本冲突

C++终止cin输入while循环时多读取^Z或^D的问题

原代码&#xff1a; istream& operator>>(istream& is, map<string, int>&mm) {string ss"";int ii0;is >> ss>>ii;mm[ss]ii;return is; }int main() {map<string,int>msi;while(cin>>msi);return 0; } 问题&…

【探讨】Java POI 处理 Excel 中的名称管理器

前言 最近遇到了一些导表的问题。原本的导表工具导不了使用名称管理器的Excel。 首先我们有两个Sheet。B1用的是名称管理器中的AAA, 而B2用的对应的公式。 第二个sheet&#xff0c;名为Test2: 这是一段简化的代码&#xff1a; public class Main {public static void mai…

【Python】将M4A\AAC录音文件转换为MP3文件

文章目录 m4aaac 基础环境&#xff1a; sudo apt-get install ffmpegm4a 要将M4A文件转换为MP3文件&#xff0c;你可以使用Python中的第三方库pydub。pydub使得音频处理变得非常简单。在开始之前&#xff0c;请确保你已经安装了pydub库&#xff0c;如果没有&#xff0c;可以通…

7.25 Qt

制作一个登陆界面 login.pro文件 QT core guigreaterThan(QT_MAJOR_VERSION, 4): QT widgetsCONFIG c11# The following define makes your compiler emit warnings if you use # any Qt feature that has been marked deprecated (the exact warnings # depend on …

【Spring】更简单的读取和存储对象,五大类注解

经过前面的学习&#xff0c;我们已经可以实现基本的 Spring 读取和存储对象的操作了&#xff0c;但在操作的过程中我们发现读取和存储对象并没有想象中的那么 “简单”&#xff0c;所以接下来我们要学习更加简单的操作 Bean 对象的方法 在 Spring 中想要更简单的存储和读取对象…

Docker镜像端口映射简介及配置指南

目录 引言&#xff1a;什么是端口映射&#xff1f;配置端口映射的步骤&#xff1a;1. 创建Docker镜像&#xff1a;2. 选择要映射的端口&#xff1a;3. 运行容器并进行端口映射&#xff1a;4. 验证端口映射&#xff1a; 示例&#xff1a;结论&#xff1a; 引言&#xff1a; Doc…

剑指YOLOv5改进最新MPDIoU损失函数(23年7月首发论文):超越现有多种G/D/C/EIoU,高效准确的边界框回归的损失,高效涨点

💡本篇内容:剑指YOLOv5改进最新MPDIoU损失函数(23年7月首发论文):超越现有多种G/D/C/EIoU,高效准确的边界框回归的损失,高效涨点 💡🚀🚀🚀本博客 改进源代码改进 适用于 YOLOv5 按步骤操作运行改进后的代码即可 💡:重点:该专栏《剑指YOLOv5原创改进》只更新…

php 单例模式

1&#xff0c;单例模式&#xff0c;属于创建设计模式&#xff0c;简单来说就是一个类只能有一个实例化对象&#xff0c;并提供一个当前类的全局唯一可访问入口&#xff1b; 2&#xff0c;例子 <?phpclass Singleton {private static $instance null;// 禁止被实例化priva…

【Linux】带你深入理解文件系统

目录 文件系统 背景知识 磁盘结构 磁盘的存储结构 磁盘抽象(逻辑&#xff0c;虚拟)结构 BootBlock&#xff1a; Super block Data blocks inode Table BlcokBitmap inode Bitmap Group Descriptor Table 文件名和inode编号 硬链接和软链接 软链接 硬链接 取消…