持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第17天,点击查看活动详情
1. ExecutorService - 执行器服务
1.1 本质
ExecutorService本质上是一个线程池
1.2 意义
减少服务器端线程的创建和销毁,做到线程的复用
1.3 组成
线程池刚创建好的时候,里面是空的,没有任何线程
1.3.1 核心线程
每过来一个请求,线程池就会生成一个线程(==核心线程 - core thread==)去处理这个请求。
核心线程的数量在创建线程池的时候需要给定
核心线程在用完之后不会销毁,而是等待下一个请求
在核心线程的数量达到指定数量之前,无论是否有空闲的核心线程,每次过来的请求都会在线程池中生成核心线程去处理,直到核心线程的数量达到了指定的数量
1.3.2 工作队列
核心线程全部被占用,后来的请求会被放入==工作队列(work queue)==中暂时存储。
工作队列本质上是一个阻塞式队列
1.3.3 临时线程
如果工作队列被全部占用,后来请求会交给==临时线程(temporary thread)==处理
临时线程的数量需要在创建线程池的时候指定
临时线程在用完之后,会存活一段指定的时间,如果超过指定时间没有接到新的任务就会被销毁
即使临时线程有空闲,也不会处理工作队列中的任务,工作队列中的任务一定是交给核心线程处理,考虑核心线程的复用
1.3.4 拒绝执行处理器
临时线程被全部占用,后来的请求会被交给==拒绝执行处理器(RejectedExecutionHandler)==来进行拒绝处理
1.4 整体图解
1.5 线程池的使用
创建线程池参数:
corePoolSize:核心线程数量maximumPoolSize:最大线程数量=核心线程数量+临时线程数量keepAliveTime:临时线程存活时间unit:存活时间单位workQueue:工作队列handler:拒绝执行处理器
public class ExecutorServiceDemo {
@Test
public void test() {
// 创建线程池
// corePoolSize:核心线程数量
// maximumPoolSize:最大线程数量,实际上是核心线程+临时线程
// keepAliveTime:临时线程存活时间
// unit:时间单位
// workQueue:工作队列
// handler:拒绝执行助手,该参数可以定义也可以不定义
ExecutorService es = new ThreadPoolExecutor(5, 10, 5000, TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<Runnable>(5), new RejectedExecutionHandler() {
});
// 执行提交的任务
// 该方法只能执行Runnable线程
es.execute(new EsDemo());
// 关闭线程池
es.shutdown();
}
}
class EsDemo implements Runnable {
@Override
public void run() {
System.out.println("hello~~~");
}
}