Java多线程自定义线程池——线程池的七大参数和四大拒绝策略

线程池

2.1 线程池思想

我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题:
如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。
那么有没有一种办法使得线程可以复用,就是执行完一个任务,并不被销毁,而是可以继续执行其他的任务?
在Java中可以通过线程池来达到这样的效果。今天我们就来详细讲解一下Java的线程池。

2.2 线程池概念

概念:其实就是一个容纳多个线程的容器,其中的线程可以反复使用,省去了频繁创建线程对象的操作,无需反复创建线程而消耗过多资源。

由于线程池中有很多操作都是与优化资源相关的,我们在这里就不多赘述。我们通过一张图来了解线程池的工作原理:
在这里插入图片描述

合理利用线程池能够带来三个好处

  1. 降低资源消耗。减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。
  2. 提高响应速度。当任务到达时,任务可以不需要的等到线程创建就能立即执行。
  3. 提高线程的可管理性。可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为消耗过多的内存,而把服务器累趴下(每个线程需要大约1MB内存,线程开的越多,消耗的内存也就越大,最后死机)。

2.3 线程池的使用

2.3.1 概述

Java里面线程池的顶级接口是java.util.concurrent.Executor,但是严格意义上讲Executor并不是一个线程池,而只是一个执行线程的工具。真正的线程池接口是java.util.concurrent.ExecutorService

要配置一个线程池是比较复杂的,尤其是对于线程池的原理不是很清楚的情况下,很有可能配置的线程池不是较优的,因此在java.util.concurrent.Executors线程工厂类里面提供了一些静态工厂,生成一些常用的线程池。官方建议使用Executors工程类来创建线程池对象。
在这里插入图片描述

3.3.2 代码实现

3.3.2.1 基于Executors类创建线程静态方法实现

Executors类中有个创建线程池的方法如下:

方法名描述
public static ExecutorService newFixedThreadPool(int nThreads)创建一个固定大小的线程池,因为采用无界的阻塞队列,所以实际线程数量永远不会变化,适用于负载较重的场景,对当前线程数量进行限制。(保证线程数可控,不会造成线程过多,导致系统负载更为严重)
public static newCachedThreadPool()用来创建一个可以无限扩大的线程池,适用于负载较轻的场景,执行短期异步任务。(可以使得任务快速得到执行,因为任务时间执行短,可以很快结束,也不会造成cpu过度切换)
public static newSingleThreadExecutor创建一个单线程的线程池,适用于需要保证顺序执行各个任务。
public static newScheduledThreadPool适用于执行延时或者周期性任务。
//使用线程池进行多线程代码执行
public class ExecutorsTest {public static void main(String[] args) {//1获取线程池对象//通过Executors工具类对应的静态方法 创建对应的线程池对象ExecutorService executorService = Executors.newFixedThreadPool(2);//2创建执行的任务对象Runnable r=new Runnable() {@Overridepublic void run() {//获取当前线程Thread thread = Thread.currentThread();System.out.println(thread.getName()+"执行了任务");try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(thread.getName()+"任务执行完毕,回归线程池");}};//3向线程池提交任务executorService.submit(r);executorService.submit(r);executorService.submit(r);//4关闭线程池executorService.shutdown();}
}

在这里插入图片描述

3.3.2.2基于ThreadPoolExecutor自定义线程池填入参数实现

ThreadPoolExecutor核心参数

Executor是线程池的顶级接口,接口中只定义了一个方法 void execute(Runnable command);线程池的操作方法都是定义子在ExecutorService子接口中的,所以说ExecutorService是线程池真正的接口。

ThreadPoolExecutor重要参数:

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

线程池四种拒绝策略

线程四种拒绝策略,当工作任务大于最大线程 + 阻塞队列会执行阻塞队列。

拒绝策略类型说明
1ThreadPoolExecutor.AbortPolicy默认拒绝策略,拒绝任务并抛出任务
2ThreadPoolExecutor.CallerRunsPolicy使用调用线程直接运行任务
3ThreadPoolExecutor.DiscardPolicy直接拒绝任务,不抛出错误
4ThreadPoolExecutor.DiscardOldestPolicy触发拒绝策略,只要还有任务新增,一直会丢弃阻塞队列的最老的任务,并将新的任务加入
public class MyThreadPoolTest {public static void main(String[] args) {//就是通过创建ThreadPoolExecutor对象 调用构造方法传入参数实现自定义线程池//如果想对线程池添加额外功能可以通过继承ThreadPoolExecutor类 实现//但是必须通过构造方法传入参数 才能实现线程池功能int initSize=3;//初始化线程池中线程个数int maxSize=5;//任务提交后没有空闲线程 扩容后线程池中线程最大个数int keepTime=0;//线程池中线程最大空闲时间(超过后会回收,直至线程数到达初始化大小)0代表不回收TimeUnit timeUnit=TimeUnit.MILLISECONDS;//空闲时间单位 毫秒,枚举类型TimeUnit.SECONDS代表分钟BlockingQueue<Runnable> queue=new LinkedBlockingQueue<>();ThreadFactory threadFactory=Executors.defaultThreadFactory();//默认线程创建工厂RejectedExecutionHandler handler= new ThreadPoolExecutor.AbortPolicy();//默认拒绝策略ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(initSize, maxSize, keepTime, timeUnit, queue, threadFactory, handler);Runnable r=new Runnable() {@Overridepublic void run() {//获取当前线程Thread thread = Thread.currentThread();System.out.println(thread.getName()+"执行了任务");try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(thread.getName()+"任务执行完毕,回归线程池");}};threadPoolExecutor.submit(r);threadPoolExecutor.submit(r);threadPoolExecutor.submit(r);threadPoolExecutor.shutdown();}
}

在这里插入图片描述

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

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

相关文章

Linux/Bizness

Enumeration nmap 用 nmap 扫描了常见的端口&#xff0c;发现对外开放了22,80,443 ┌──(kali㉿kali)-[~] └─$ nmap 10.10.11.252 Starting Nmap 7.93 ( https://nmap.org ) at 2024-03-08 01:21 EST Nmap scan report for 10.10.11.252 Host is up (0.36s latency). Not…

python 空间距离计算

目录 python 空间距离计算 已知两点&#xff0c;画三角形 批量矩阵计算 python 空间距离计算 要在空间中找到一个点&#xff0c;使其位于点 b 和 c 之间的连线上&#xff0c;并且与点 b 的距离等于点 a 到点 b 的距离的2倍。 import numpy as npif __name__ __main__:a …

MySQL下载安装和本地连接

1、下载MySQL 从MySQL官网下载MySQL Community Server版本&#xff1a; 下载地址&#xff1a;MySQL官网 1、进入官网&#xff0c;点击DOWNLOADS 2、点击MySQL Community(GPL)Downloads 3、点击MySQL Installer for Windows 4、这个会直接跳转到最新的版本 如果想下载以往的…

题目:笨笨机器人(蓝桥OJ 3262)

问题描述&#xff1a; 解题思路&#xff1a; 用n位二进制数每位来表示每一步的状态&#xff0c;2的n次幂即使全部可能。遍历计算全部符合题意总数&#xff0c;再用cnt/(2的n次幂&#xff09;即答案。 需要注意的是&#xff0c;四舍五入后四位的方法&#xff1a;round(),可以四舍…

计算机网络——数据链路层(数据链路层功能概述)

计算机网络——数据链路层&#xff08;数据链路层功能概述&#xff09; 数据链路层的功能数据链路层的基本概念封装成帧和透明传输 我们之前已经学完了物理层的所有内容&#xff0c;今天开始我们要进入数据链路层的学习&#xff0c;如果有小伙伴对物理层的内容感兴趣的话&#…

from_pretrained 做了啥

transformers的三个核心抽象类是Config, Tokenizer和Model&#xff0c;这些类根据模型种类的不同&#xff0c;派生出一系列的子类。构造这些派生类的对象也很简单&#xff0c;transformers为这三个类都提供了自动类型&#xff0c;即AutoConfig, AutoTokenizer和AutoModel。三个…

算法系列--动态规划--子序列(2)

&#x1f495;"你可以说我贱&#xff0c;但你不能说我的爱贱。"&#x1f495; 作者&#xff1a;Mylvzi 文章主要内容&#xff1a;算法系列–动态规划–子序列(2) 今天带来的是算法系列--动态规划--子序列(2),包含了关于子序列问题中较难的几道题目(尤其是通过二维状…

数据结构从入门到精通——快速排序

快速排序 前言一、快速排序的基本思想常见方式通用模块 二、快速排序的特性总结三、三种快速排序的动画展示四、hoare版本快速排序的代码展示普通版本优化版本为什么要优化快速排序代码三数取中法优化代码 五、挖坑法快速排序的代码展示六、前后指针快速排序的代码展示七、非递…

VSCode最强插件合集,助你代码开发效率翻倍!

大家好&#xff0c;我是宝哥。 今天给大家推荐14个VSCode靠前的编程辅助插件&#xff0c;它们可以帮助你提高代码编写、调试、阅读和管理效率。 1.ESLint 简介&#xff1a;用于检查JavaScript代码的语法和风格错误。 功能特色&#xff1a;支持多种规则&#xff0c;可以自定义规…

XSS-labs详解

xss-labs下载地址https://github.com/do0dl3/xss-labs 进入靶场点击图片&#xff0c;开始我们的XSS之旅&#xff01; Less-1 查看源码 代码从 URL 的 GET 参数中取得 "name" 的值&#xff0c;然后输出一个居中的标题&#xff0c;内容是 "欢迎用户" 后面…

STM32利用串口标准库发送字节,发送数组,发送字符串,发送数字,实现printf功能。

早晨到现在刚刚完成的功能&#xff1a;发送字节&#xff0c;发送数组&#xff0c;发送字符串&#xff0c;发送数字&#xff0c;实现printf功能。 当然这是建立在昨天学习使用串口发送数据的基础上&#xff0c;新建立的功能函数&#xff0c;咱们先来看看这次实验的结果吧&#…

C语言经典算法-8

文章目录 其他经典例题跳转链接41.基数排序法42.循序搜寻法&#xff08;使用卫兵&#xff09;43.二分搜寻法&#xff08;搜寻原则的代表&#xff09;44.插补搜寻法45.费氏搜寻法 其他经典例题跳转链接 C语言经典算法-1 1.汉若塔 2. 费式数列 3. 巴斯卡三角形 4. 三色棋 5. 老鼠…

安捷伦Agilent E8364C网络分析仪

181/2461/8938产品概述&#xff1a; Agilent E8364C 网络分析仪是 Agilent PNA 系列网络分析仪&#xff08;高性能网络分析仪&#xff09;的一部分&#xff0c;具有满足您关键需求的最高准确度。Agilent E8364C 具有 10 MHz 至 50 GHz 的宽频率范围&#xff0c;并具有 2 个端口…

刀具磨损失效形式

目录 磨料磨损 扩散磨损 粘着磨损 腐蚀磨损 氧化磨损 表面疲劳磨损 热点磨损 刀具失效形式有磨损、破损和折断。在微小孔钻削中&#xff0c;磨损形式有很多种&#xff0c;如磨料磨损、扩散磨损、粘着磨损、腐蚀磨损、氧化磨损、表面疲劳磨损、热点磨损等。 磨料磨损 磨…

python电影院订票信息管理系统flask-django-php-nodejs

当今社会已经步入了科学技术进步和经济社会快速发展的新时期&#xff0c;国际信息和学术交流也不断加强&#xff0c;计算机技术对经济社会发展和人民生活改善的影响也日益突出&#xff0c;人类的生存和思考方式也产生了变化。传统电影院订票采取了人工的管理方法&#xff0c;但…

leetcode 20.有效的括号 JAVA

题目 思路 括号的匹配&#xff0c;这是一道经典的栈的应用问题。 给我们一个字符串&#xff0c;当我们遍历到左括号时&#xff0c;让其入栈。当我们遍历到右括号时&#xff0c;让栈顶元素出栈&#xff0c;看看栈顶的元素是否和遍历到的右括号匹配。不匹配的话直接false,匹配的…

基于FPGA的FFT图像滤波设计

1.FFT滤波算法介绍 FFT滤波就是通过傅里叶运算将图像转换到频域空间&#xff0c;然后在频域中对图像进行处理&#xff0c;最后将处理后的图像通过傅里叶逆运算将图像转会到时域空间。 在频域空间中&#xff0c;我们能够更好的对图像的噪声进行分析&#xff0c;然后找出相关规律…

Kubernetes(k8s)集群健康检查常用的五种指标

文章目录 1、节点健康指标2、Pod健康指标3、服务健康指标4、网络健康指标5、存储健康指标 1、节点健康指标 节点状态&#xff1a;检查节点是否处于Ready状态&#xff0c;以及是否存在任何异常状态。 资源利用率&#xff1a;监控节点的CPU、内存、磁盘等资源的使用情况&#xf…

YOLOv8 | 注意力机制 | ShuffleAttention注意力机制 提升检测精度

YOLOv8成功添加ShuffleAttention ⭐欢迎大家订阅我的专栏一起学习⭐ &#x1f680;&#x1f680;&#x1f680;订阅专栏&#xff0c;更新及时查看不迷路&#x1f680;&#x1f680;&#x1f680; YOLOv5涨点专栏&#xff1a;http://t.csdnimg.cn/1Aqzu YOLOv8涨点专栏…

mysql字段多个值,mybatis/mybatis-plus匹配查询

mysql中有一个字段是字符串类型的&#xff0c;category字段值有多个用逗号分割的&#xff0c;例如&#xff1a;娱乐,时尚美妆,美食 。现在想实现这么一个功能&#xff0c; 前端传参 字符串&#xff0c;美食,娱乐。现在想在mybatis的xml中实现&#xff0c;查询&#xff0c;能查到…