当前位置:网站首页>线程池(通俗易懂)
线程池(通俗易懂)
2022-04-22 23:29:00 【crazyK.】
目录
一、什么是线程池
线程池其实就是一种多线程处理形式,处理过程中可以将任务添加到队列中,然后在创建线程后自动启动这些任务。这里的线程就是我们前面学过的线程,这里的任务就是我们前面学过的实现了Runnable或Callable接口的实例对象。
线程池的优点:降低资源消耗、提高响应速度、方便管理;线程可以复用、可以控制最大并发数、可以管理线程
二、创建线程池的方式
| 方式 | 描述 |
| Executors.newSingleThreadExecutor(); | 创建一个单一的线程池 |
| Executors.newFixedThreadPool(int nThreads); | 创建一个固定大小的线程池,参数填线程池大小 |
| Executors.newCachedThreadPool(); | 创建一个可伸缩的线程池,遇强则强,遇弱则弱 |
public class ThreadPoolTest {
public static void main(String[] args) {
ExecutorService threadPool = Executors.newSingleThreadExecutor();
//ExecutorService threadPool = Executors.newFixedThreadPool(5);
//ExecutorService threadPool = Executors.newCachedThreadPool();
try {
for (int i = 1; i <= 10; i++) {
//在execute中丢入一个Runnable ---> lambda 表达式
threadPool.execute(()->{
System.out.println(Thread.currentThread().getName());
});
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//使用完毕后,程序结束,关闭线程池
threadPool.shutdown();
}
}
}



三、线程池的七大参数
| 参数 | 描述 |
| int corePoolSize | 核心线程池大小 |
| int maximumPoolSize | 最核心大线程池大小 |
| long keepAliveTime | 超时时间 没有人使用会自动释放 |
| TimeUnit unit | 超时单位 |
| BlockingQueue<Runnable> workQueue | 阻塞队列 |
| ThreadFactory threadFactory | 线程工厂,创建线程的,一般不用动 |
| RejectedExecutionHandler handler | 拒绝策略 |
在上面线程池的三种创建方式种中,点进源码,可以看到它们都new 了一个 ThreadPoolExecutor
//newSingleThreadExecutor
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1, //核心线程,最大线程为 1
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
//newFixedThreadPool
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads, //核心线程,最大线程为传进来的参数
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
//newCachedThreadPool
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,//核心线程默认是0,最大线程为21亿
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
ThreadPoolExecutor 中就包含了线程池的七大参数
// ThreadPoolExecutor
public ThreadPoolExecutor(int corePoolSize, //核心线程池大小
int maximumPoolSize, //最核心大线程池大小
long keepAliveTime, //超时时间 没有人使用会自动释放
TimeUnit unit, // 超时单位
BlockingQueue<Runnable> workQueue, // 阻塞队列
ThreadFactory threadFactory, // 线程工厂,创建线程的,一般不用动
RejectedExecutionHandler handler// 拒绝策略
) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.acc = System.getSecurityManager() == null ?
null :
AccessController.getContext();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
四、四种拒绝策略
| 拒绝策略 | 描述 |
| new ThreadPoolExecutor.AbortPolicy() | 线程池默认拒绝策略,如果元素添加到线程池失败,会抛出RejectedExecutionException异常 |
| new ThreadPoolExecutor.CallerRunsPolicy() | 如果添加失败,那么主线程会自己调用执行器中的execute方法来执行任务 |
| new ThreadPoolExecutor.DiscardPolicy() | 如果添加失败,则放弃,不会抛出异常 |
| new ThreadPoolExecutor.DiscardOldestPolicy() | 如果添加到线程池失败,会将队列中最早添加的元素移除,再尝试添加,如果失败则按该策略不断重试 |
场景见下面的自定义线程池:核心线程数-2;最大核心线程数 - 5;阻塞队列 - 3 可容纳最大请求数 - 8
1.AbortPolicy()
分别将请求数设置为5,8,9



2.CallerRunsPolicy()
将请求数量设置为9,不超过最大容量的情况都相同

3.DiscardPolicy()
将请求数量设置为9,不超过最大容量的情况都相同

4.DiscardOldestPolicy()
将请求数量设置为9,不超过最大容量的情况都相同
新请求把旧请求顶替

五、自定义一个线程池
1.场景描述
银行办理业务
平时银行只开放两个办理业务窗口,当两个窗口都有人时,新来的客户会进入侯客厅等待,当人过多时3,4,5窗口会打开进行业务办理


其实这种场景就与线程池类似,如下图:

2.代码实现
public class ManualPool {
public static void main(String[] args) {
ExecutorService threadPool = new ThreadPoolExecutor(
2, //核心线程池大小
5, //最大核心线程池大小
3, //超时时间
TimeUnit.SECONDS, //超时单位
new LinkedBlockingQueue<>(3), //阻塞队列 --> 相当于银行的候客区
Executors.defaultThreadFactory(), //线程工厂
new ThreadPoolExecutor.DiscardOldestPolicy() //拒绝策略
);
try {
//最大容量 = 阻塞队列大小 + 最大核心线程池大小
for (int i = 1; i <= 9; i++) {
//在execute中丢入一个Runnable ---> lambda 表达式
//使用线程池来创建线程
threadPool.execute(()->{
System.out.println(Thread.currentThread().getName());
});
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//使用完毕后,程序结束,关闭线程池
threadPool.shutdown();
}
}
}
版权声明
本文为[crazyK.]所创,转载请带上原文链接,感谢
https://blog.csdn.net/weixin_57504474/article/details/124348084
边栏推荐
- How can Cassandra, an open source database giant, tell a "new story" in China without talking about the track and the tuyere
- 51 单片机学习_4-2 数码管动态显示
- 想开户交易农产品期货如玉米、豆粕等,该如何开户?
- 【经验分享】分享 MangoPapa 的论文学习经验
- L1-049 ladder race seat allocation (20 points) (in-depth understanding of for loop + three-dimensional array + error analysis)
- 如何快速转载CSDN中的博客
- Chenshi industrial machine vision | weld detection solution
- 读《Software Engineering at Google》(12)
- 邀请你参与字节跳动 UME 插件开发竞赛
- High number | [differential calculus and application of multivariate functions] error prone problems and detailed explanation of Li Lin 880
猜你喜欢

居家第二十二天的绿豆芽

Enter a formula in the Visio text box

JSON. In golang Marshall pit

【Objective-C 高级编程】—— GCD

codeforce round#784(div4) A-H
![[leetcode refers to the path with a certain value in offer 34. Binary tree (medium)]](/img/3d/efb4114ba00a72ef69089445b15e7f.png)
[leetcode refers to the path with a certain value in offer 34. Binary tree (medium)]

【DVCon2020】基于多线程UVM测试平台的仿真加速方法

【PCIe 实战】SNPS PCIe 开启 SRIS mode

【DVCon2020】基于Signoff Abstract Model的低功耗设计层级验证加速

编写程序,实现电子时钟自动走动的效果并提供一个按钮控制电子时钟是否停止走动。
随机推荐
Numeric type and sequence type
Design of optical fingerprint module unlocking scheme fingerprint lock scheme
MySQL log retention policy: set binlog log storage days and file size limit
旅行箱指纹锁方案pcb电路板方案
Django指定数据库的时候报No module named ‘django_test.settings‘
Financial information security training -- 22 / 4 / 19 (Part 2)
[Error]dyld: Library not loaded:
SQL数据库基础知识
Go timer time Ticker
Excel VBA multi condition screening and summary statistics
【PCIe 6.0】PCIe 6.0 新特性 - DMWr (Deferrable Memory Write) 详解
[原创][开源]C# Winform DPI自适应方案,SunnyUI三步搞定
古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,每个月的兔子总数为多少?
Esp32 (GPIO) - GPIO learning (5)
【毅力挑战】PCIe 每日一问一答(2022.03 归档)
登录功能&新增文章功能的测试点提取以及测试用例编写
读《Software Engineering at Google》(14)
Enter a formula in the Visio text box
Pytorch 卷积核填充和步幅、多输入多输出通道、池化层
Where is London gold safer to open an account?