一、线程池介绍
线程池(Thread Pool)是一种基于多线程处理的服务器架构,它预先创建并维护一组线程,用于处理异步任务或并发请求。线程池的设计目的是减少创建和销毁线程的开销,提高系统的响应速度和吞吐量。
(一)线程池的主要核心原理
- 创建一个池子,池子中是空的。
- 提交任务时,池子会创建新的线程对象,任务执行完毕,线程归还给池子。下次再次提交任务时,不需要创建新的线程,直接复用已有的线程即可。
- 但是如果提交任务时,池子中没有空闲线程,也无法创建新的线程,任务就会排队等待。
二、线程池代码实现
实现步骤:
- 创建线程池
- 提交任务
- 所有的任务全部执行完毕,关闭线程池
Excutors:线程池的工具类通过调用方法返回不同类型的线程池对象。
public static ExecutorService newCachedThreadPool(); 创建一个没有上限的线程池
public static ExecutorService newFixedThreadPool(int nThreads); 创建有上限的线程池
(一)创建一个没有上限的线程池
public class MyThreadPoolDemo {
public static void main(String[] args) throws InterruptedException {
// 创建一个没有上限的线程池
ExecutorService pool1 = Executors.newCachedThreadPool();
// 提交任务
pool1.submit(new MyRunnable());
pool1.submit(new MyRunnable());
pool1.submit(new MyRunnable());
pool1.submit(new MyRunnable());
pool1.submit(new MyRunnable());
// 3.销毁线程池(一般不销毁)
// pool1.shutdown();
}
}
class MyRunnable implements Runnable {
@Override
public void run() {
for (int i = 1; i <= 3; i++) {
System.out.println(Thread.currentThread().getName() + "----" + i);
}
}
}
运行结果:提交一个新任务,就创建一个新的线程
(二)创建有上限的线程池
public class MyThreadPoolDemo {
public static void main(String[] args) throws InterruptedException {
// 创建有上限的线程池
ExecutorService pool1 = Executors.newFixedThreadPool(3);
// 提交任务
pool1.submit(new MyRunnable());
pool1.submit(new MyRunnable());
pool1.submit(new MyRunnable());
pool1.submit(new MyRunnable());
pool1.submit(new MyRunnable());
// 3.销毁线程池(一般不销毁)
// pool1.shutdown();
}
}
class MyRunnable implements Runnable {
@Override
public void run() {
for (int i = 1; i <= 3; i++) {
System.out.println(Thread.currentThread().getName() + "----" + i);
}
}
}
运行结果:无论提交多少个新任务,只会创建指定线程数
三、自定义线程池——ThreadPoolExecutor
(一)自定义线程池的七个参数
参数 | 参数解释 | 参数范围 |
---|---|---|
int corePoolSize | 核心线程数量 | 不能小于0 |
int maximumPoolSize | 最大线程数量 | 不能小于等于0,最大数量>=核心线程数 |
long keepAliveTime | 空闲线程最大存活空间 | 不能小于0 |
TimeUnit unit | 时间单位 | 用TimeUnit指定 |
BlockingQueue<Runnable> workQueue | 任务队列 | 不能为null |
ThreadFactory threadFactory | 创建线程工厂 | 不能为null |
RejectedExecutionHandler handler | 任务的拒绝策略 | 不能为null |
自定义线程池任务拒绝策略
设置核心线程数为3,最大线程数为6,队列长度为3:
提交3个任务:此时线程池中就会创建3个线程来处理这3个任务;
提交5个任务:此时线程池中会创建3个线程来处理3个任务,剩余的2个任务就会在任务队列中排队等待,等有了空余的线程,后面2个任务才会被执行;
提交8个任务:此时线程池中会创建3个线程来处理3个任务,后面3个任务就会在队列中排队等待,线程池创建临时线程处理剩下2个任务;
因此,创建临时线程的条件:核心线程都在运行,任务队列中已经排满了,才会创建临时线程处理后面的任务。
任务在执行的时候,并不一定会按照提交的顺序来执行,先提交的任务不一定先执行。
提交10个任务:此时提交的任务数量已经超过了最大线程数+队列长度。处理方案:线程池中会创建3个线程来处理3个任务,有3个任务在队列中等待,线程池中会创建3个临时线程处理3个任务,剩下1个任务就会触发任务的拒绝策略。
(二)最大并行数
使用代码可以获取当前电脑的最大并行数:
public class MyThreadPoolDemo2 {
public static void main(String[] args) {
int count = Runtime.getRuntime().availableProcessors();
System.out.println(count); // 6
}
}
标签:MyRunnable,创建,任务,线程,new,JavaSE,多线程,pool1 From: https://blog.csdn.net/Helen_1997_1997/article/details/129843128线程池的大小:
计算比较多,读取本地文件和连接数据库的操作比较少,使用:
CPU密集型运算:最大并行数+1
读取本地文件和连接数据库的操作比较多,使用:
I/O密集型运算:最大并行数 * 期望CPU利用率 * (总时间(CPU计算时间+等待时间) / CPU计算时间)