<JavaEE> 经典设计模式之 -- 线程池

目录

一、线程池的概念

二、Java 标准库中的线程池类

2.1 ThreadPoolExecutor 类

2.1.1 corePoolSize 和 maximumPoolSize

2.1.2 keepAliveTime 和 unit

2.1.3 workQueue

2.1.4 threadFactory

2.1.5 handler

2.1.6 创建一个参数自定义的线程池

2.2 Executors 类

2.3 实现自己的线程池


一、线程池的概念

1)什么是线程池?

准备预期需要使用的对象,将这些对象放入一个可以随时取用的容器中,这个容器就被称为“池”。

使用过的对象也不立刻销毁,而是放回“池”中,以备下次使用。

将线程作为上述对象,放在一个容器中,这就称为“线程池”。

2)为什么使用线程池?
在实际使用中,“线程池”并没有频繁的创建和销毁线程,而是从“池”中存取线程,这样可以减少每次启动和销毁线程的损耗,提高运行效率,减小系统开销。
3)为什么使用线程池可以提高效率?

通常创建线程,是通过向系统申请创建,需要通过系统内核完成,是具有内核态的代码。

而从线程池中存取线程,是属于用户态的代码,相比于内核态代码更可控、稳定,操作更快。


二、Java 标准库中的线程池类

2.1 ThreadPoolExecutor 类

这个类的构造方法参数众多,包含以下参数:

int corePoolSize

核心线程数

int maximumPoolSize

最大线程数

long keepAliveTime

空闲线程存活时间

TimeUnit unit

时间单位

BlockingQueue<Runnable> workQueue

任务队列

ThreadFactory threadFactory

线程工厂

RejectedExecutionHandler handler

拒绝策略

2.1.1 corePoolSize 和 maximumPoolSize

int corePoolSize 核心线程数

线程池中保持持有的最小线程数量。

int maximumPoolSize 最大线程数

线程池中可以持有的最大线程数量。
标准库提供的线程池,持有的线程数量是可以变动的,可以根据需要执行的任务数量,自适应线程的数量。

2.1.2 keepAliveTime 和 unit

long keepAliveTime 空闲线程存活时间

当线程池中的线程处于空闲状态时,会等待 keepAliveTime 时间后自动关闭。

如果keepAliveTime为0,线程在执行完任务后则不会关闭。

TimeUnit unit 时间单位
keepAliveTime 空闲线程存活时间的时间单位。

2.1.3 workQueue

BlockingQueue<Runnable> workQueue 任务队列

用于存储等待执行的任务。当线程池中的线程数量达到最大值时,新任务将被添加到队列中等待执行。

执行的任务应该是 Runnable 接口的实现类,

2.1.4 threadFactory

前置知识点:工厂模式

什么是工厂模式?

工厂模式(Factory Pattern)是一种创建型设计模式,它提供了一种在不指定具体类的情况下创建对象的接口。

工厂模式的核心思想是,将对象的创建过程抽象出来,使得使用者的创建与类的实例化过程解耦。

在工厂模式中,会实现一个工厂类,它提供一个创建对象的接口,而使用者只需要调用这个接口即可,工厂类会根据客户端的请求,返回不同类型的对象。

threadFactory 具体指什么:

ThreadFactory threadFactory 线程工厂
通过工厂类创建线程对象(简单理解就是通过这个类产出线程)。ThreadFactory 是一个接口,接口中只中有一个方法 newThread 方法,通过覆写该方法获得一个线程,同时可以给这个新线程设置一些属性。

2.1.5 handler

RejectedExecutionHandler handler 拒绝策略
线程池异常处理器,也称拒绝策略。这里的 handler 表示一个实现了 RejectedExecutionHandler 接口的实现类,传入的 handler 参数决定了出现异常时,线程池如何处理异常。
有哪几种拒绝策略,分别表示什么?
ThreadPoolExecutor.AbortPolicy当线程池满时,如果新任务无法执行,则立即抛出 RejectedExecutionException 异常,是默认策略。
ThreadPoolExecutor.CallerRunspolicy当线程池满时,如果新任务无法执行,则由调用线程自己执行新任务。
ThreadPoolExecutor.DiscardOldestPolicy当线程池满时,如果新任务无法执行,则丢弃最早添加的任务,然后执行新任务。
ThreadPoolExecutor.DiscardPolicy当线程池满时,如果新任务无法执行,则丢弃新任务,不执行。

2.1.6 创建一个参数自定义的线程池

创建并运行以下线程池和任务:

分析上述代码运行结果:

2.2 Executors 类

1)简单介绍 Executors 类
ThreadPoolExecutor 类参数较多,使用较复杂。因此,为方便使用,标准库中又提供了 Executors 类。Executors 类是对 ThreadPoolExecutor 类进行了一层封装,是一个工厂类,通过这个类创建出不同属性的线程池对象。
2)简单介绍常用的 Executors 类创建线程池的方法

newFixedThreadPool

创建固定线程数的线程池

newCachedThreadPool

创建线程数目动态增长的线程池

newSingleThreadExecutor

创建只包含单个线程的线程池

newScheduledThreadPool

创建可以定时执行任务的线程池
3)开发过程中应该使用 ThreadPoolExecutor 类还是使用 Executors 类?

ThreadPoolExecutor 类参数较多、可以自定义,这意味着使用这个类创建的线程池更灵活。

而 Executors 类相比 ThreadPoolExecutor 类多了一层封装,部分参数已经设定好,这使得 Executors 类在使用上更便利。

这两种选择,前者更偏向于高度定制化的线程池,而后者偏向于通用性。两者并无高下之分,各有偏向,使用者根据实际应用场景使用即可。

2.3 实现自己的线程池

线程池的使用有以下关键点:

<1>

线程池,肯定要有线程。在这里实现一个线程数量固定的线程池,就需要在这个类的构造方法中,根据输入的参数 n ,新建 n 个线程。
<2>维护一个阻塞队列,队列持有需要执行的任务。
<3>提供一个 submit 方法,用于将任务添加到任务队列中。
<4>线程池中的线程,也有自己的任务,就是不断地扫描任务队列,如果队列中有任务,则取出任务后执行。
<5>注意新建的线程需要有合适的启动时机。在以下实现中,我们让线程一创建就启动。

代码演示线程池的实现:

class MyThreadPool{//创建一个用于存放任务的队列;private BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(5);//构造方法,用于构造线程池。方法中需要将线程new出来;public MyThreadPool(int n){//设置线程需要执行的任务;Runnable runnable = new  Runnable() {@Overridepublic void run() {while (true){try {//从任务队列中取出任务,并执行;queue.take().run();} catch (InterruptedException e) {e.printStackTrace();}}}};//循环创建线程,并启动,将线程放入队列中;for (int i = 0; i < n; i++){Thread t = new Thread(runnable);t.start();}}//添加任务方法。往任务队列中添加任务;public void submit(Runnable runnable) throws InterruptedException {queue.put(runnable);}
}
public class ThreadPool_Demo35 {public static void main(String[] args) throws InterruptedException {//新建线程池;MyThreadPool threadPool = new MyThreadPool(2);//给线程池添加任务;for (int i= 0; i < 10; i++){int n = i;threadPool.submit(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + " 执行任务:" + n);}});}}
}//运行结果:
Thread-0 执行任务:0
Thread-1 执行任务:1
Thread-0 执行任务:2
Thread-1 执行任务:3
Thread-0 执行任务:4
Thread-0 执行任务:6
Thread-0 执行任务:7
Thread-0 执行任务:8
Thread-0 执行任务:9
Thread-1 执行任务:5
...十个任务全部成功打印。
应该注意到,线程没有执行结束,还在等待新的任务加入,这是线程池的合理功能。

阅读指针 -> 《 Synchronized 锁进阶》

链接生成中..........

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

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

相关文章

go学习笔记(17)Blob and ArrayBuffer

最近在学习go websocket的时候&#xff0c;在学习实验过程遇到一个比较奇怪问题。为什么我的数据返回是blob&#xff0c;而不是arrayBuffer&#xff1f;百思不得其解。 直到同事打包的时候微信小游戏遇到了一个报错。FileReader不支持。 经过在社区查询&#xff0c;官方答复是…

[RoBERTa]论文实现:RoBERTa: A Robustly Optimized BERT Pretraining Approach

文章目录 一、完整代码二、论文解读2.1 模型架构2.2 参数设置2.3 数据2.4 评估 三、对比四、整体总结 论文&#xff1a;RoBERTa&#xff1a;A Robustly Optimized BERT Pretraining Approach 作者&#xff1a;Yinhan Liu, Myle Ott, Naman Goyal, Jingfei Du, Mandar Joshi, Da…

P10 Linux进程编程 fork创建子进程

目录 前言 01 fork()创建子进程 示例 1使用 fork()创建子进程。 02 fork创建新进程时发生了什么事&#xff1f; 2.1 父、子进程中对应的文件描述符指向了相同的文件表 前言 &#x1f3ac; 个人主页&#xff1a;ChenPi &#x1f43b;推荐专栏1: 《Linux C应用编程&#xf…

异步回调模式

异步回调 所谓异步回调&#xff0c;本质上就是多线程中线程的通信&#xff0c;如今很多业务系统中&#xff0c;某个业务或者功能调用多个外部接口&#xff0c;通常这种调用就是异步的调用。如何得到这些异步调用的结果自然也就很重要了。 Callable、Future、FutureTask publi…

半导体划片机助力氧化铝陶瓷片切割:科技与工艺的完美结合

在当今半导体制造领域&#xff0c;氧化铝陶瓷片作为一种高性能、高可靠性的材料&#xff0c;被广泛应用于各种电子设备中。而半导体划片机的出现&#xff0c;则为氧化铝陶瓷片的切割提供了新的解决方案&#xff0c;实现了科技与工艺的完美结合。 氧化铝陶瓷片是一种以氧化铝为基…

《巫师3》缺失vcomp110.dll如何解决,如何快速修复vcomp110.dll丢失问题

在日常使用电脑的过程中&#xff0c;我们可能会遇到一些错误提示&#xff0c;其中之一就是“vcomp110.dll丢失”。这个错误提示通常意味着vcomp110.dll文件在系统中无法找到或加载。那么&#xff0c;vcomp110.dll丢失的原因是什么&#xff1f;它对电脑有什么影响&#xff1f;本…

高德地图vue实现自定义标点热力图效果(缩放时展示不同数据)

高德地图插件引入省略。。。样式和vue基础组件省略。。。 如果每个标点没有数值&#xff0c;则可以用点聚合来实现功能下面例子&#xff0c;每个标点会有按市统计的数值&#xff0c;而且缩放一定程度时&#xff0c;需要展示按省统计的标点&#xff0c;因此需要自定义标点样式和…

leetcode刷题日志-54螺旋矩阵

思路&#xff1a; 上下左右设置四个边界 每走完一行或者一列&#xff0c;移动相应边界&#xff0c;当左边界大于右边界&#xff0c;或者上边界大于下边界时&#xff0c;结束 代码如下&#xff1a; class Solution {public List<Integer> spiralOrder(int[][] matrix) {…

线程上下文切换

线程上下文切换 巧妙地利用了时间片轮转的方式, CPU 给每个任务都服务一定的时间&#xff0c;然后把当前任务的状态保存下来&#xff0c;在加载下一任务的状态后&#xff0c;继续服务下一任务&#xff0c;任务的状态保存及再加载, 这段过程就叫做上下文切换。时间片轮转的方式…

冒泡排序和直接选择排序(C/C++实现)

文章目录 冒泡排序(交换排序&#xff09;基本思想特性总结代码实现 直接选择排序基本思想特性总结代码实现&#xff08;优化&#xff0c;每次循环同时选择最小和最大的数&#xff09; 冒泡排序(交换排序&#xff09; 基本思想 基本思想&#xff1a;所谓交换&#xff0c;就是根…

class065 A星、Floyd、Bellman-Ford与SPFA【算法】

class065 A星、Floyd、Bellman-Ford与SPFA【算法】 2023-12-9 19:27:02 算法讲解065【必备】A星、Floyd、Bellman-Ford与SPFA code1 A*算法模版 // A*算法模版&#xff08;对数器验证&#xff09; package class065;import java.util.PriorityQueue;// A*算法模版&#xff…

两年外包生涯做完,感觉自己废了一半。。。。。

先说一下自己的情况&#xff0c;本科生&#xff0c;19年通过校招进入南京某软件公司&#xff0c;干了接近2年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了2年的功能测试&…

laravel的ORM 对象关系映射

Laravel 中的 ORM&#xff08;Eloquent ORM&#xff09;是 Laravel 框架内置的一种对象关系映射系统&#xff0c;用于在 PHP 应用中与数据库进行交互。Eloquent 提供了一种优雅而直观的语法&#xff0c;使得开发者可以使用面向对象的方式进行数据库查询和操作。 定义模型&…

结合ColorUI组件开发微信小程序

1.自定义组件生命周期函数&#xff1a; Component({data: {},attached() {console.log("自定义组件生命周期函数 attached--先执行");this.getPos();},ready() {console.log("ready生命周期函数---在attached之后执行")},methods: {getPos() {var that th…

数据结构:位图、布隆过滤器以及海量数据面试题

位图、布隆过滤器以及海量数据面试题 1.位图1.1概念1.2实现1.3位图应用 2.布隆过滤器2.1布隆过滤器的提出2.2布隆过滤器的概念2.3布隆过滤器的查找2.4布隆过滤器的实现2.5布隆过滤器的删除2.6布隆过滤器的优点2.7布隆过滤器的缺点 3.海量数据面试题3.1哈希切分3.2位图应用3.3布…

如何成为前1%的程序员

如果你想成为前1%的程序员&#xff0c;你必须遵循1%的程序员做什么&#xff0c;了解其他99%的人不做什么。在现代&#xff0c;我们有各种学习平台&#xff0c;里面充满了与编程相关的视频、图文以及其他资料。 举例来说&#xff0c;我作为编程的初学者&#xff0c;去寻找路线图…

IDEA2023找不到add framework support怎么解决

问题: 我的idea版本是2023.01&#xff0c;新版idea右键项目没有Add Framework Support&#xff0c;help里面也找不到相关的。 从project structue的facets里面添加就行了&#xff0c;都是一样的。 1.依旧是新建一个项目 2.file-->project structure--->facets 左上角加…

Android studio如何安装ai辅助工具

引言 在没有翻墙的情况下&#xff0c;即单纯在公司打工&#xff0c;经测试&#xff0c;大部分ai工具都是使用不了的&#xff08;比如各种gpt,codeium,copilot&#xff09;&#xff0c;根本登录不了账号&#xff0c;但有一个国内的codegeex是可以使用的&#xff0c;在这里不对各…

Android app性能优化指南

Android应用性能优化指南 提高应用程序的性能以实现更流畅的用户体验和更高的可见度。 性能在任何应用程序的成功中发挥着重要的作用。为用户提供流畅无缝的体验应该是开发人员的重点。 应用程序大小 在用户开始使用我们的应用程序之前&#xff0c;他们需要下载应用程序并将…

DTCC2023大会-DBdoctor-基于eBPF观测数据库-附所有PPT下载链接

DTCC2023大会-DBdoctor-基于eBPF观测数据库-附所有PPT下载链接 8月16日—18日,第14届中国数据库技术大会(DTCC-2023)在北京国际会议中心举行。聚好看在大会上首次发布基于eBPF观测数据库性能的产品DBdoctor&#xff0c;受到了业界广泛的关注。近期几位业内同仁过来要大会的PPT…