线程池必知三点
三个构造方法,四个拒绝策略,七个实例化元素
1、普通的线程创建方式有以下三种
//创建单个线程
ExecutorService s1 = Executors.newSingleThreadExecutor();
//创建固定的线程数,需要给定参数
ExecutorService s2 = Executors.newFixedThreadPool(3);
//根据需要创建线程,最大数为Integer.MAX_VALUE
ExecutorService s3 = Executors.newCachedThreadPool();
2、阿里巴巴开发手册推荐使用以下方式创建线程
//上述三个构造方法底层其实也是调用这个构造器,只是传入的参数不同
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
3、方法参数解析
corePoolSize 线程池中核心的线程数,如下图是3
maximumPoolSize 池中最大的线程数,如下图是6
keepAliveTime 当线程数大于核心时,多余的空闲线程
(maximumPoolSize -corePoolSize)在终止之前等待新任务的最长时间。
unit 时间单位
workQueue 阻塞队列,用来作为候客区
threadFactory 创建线程的工厂
handler 线程数超出max之后的处理策略,有四种
由上图可以写出下面的测试类:
import java.util.concurrent.*;
/**
* @Author: Mr.Chen
* @Description: 创建线程池
* @Date:Created in 10:19 2020/8/16
*/
public class TestPool {
public static void main(String[] args) {
ExecutorService service = new ThreadPoolExecutor(3,6,3,
TimeUnit.SECONDS,
new LinkedBlockingDeque<>(4),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()
);
try {
for (int i = 1; i <= 9; i++) {
service.execute(() -> {
System.out.println(Thread.currentThread().getName());
});
}
} finally {
service.shutdown();
}
}
}
//测试结果
1、线程数1-3,执行线程数为1-3
2、线程数为3-6个,执行线程数在3-6之间,一一对应
3、线程数为6-10个,一次执行6个,多余的放在阻塞队列中
4、线程数大于10个,根据策略做出响应
4、四种拒绝策略
线程数大于maximumPoolSize + workQueue时的四种策略
1、new ThreadPoolExecutor.AbortPolicy() //不处理,直接抛出异常
2、new ThreadPoolExecutor.CallerRunsPolicy() //返回执行原先的线程,一般为main线程
3、new ThreadPoolExecutor.DiscardPolicy() //直接丢弃任务
4、new ThreadPoolExecutor.DiscardOldestPolicy() //丢弃最旧的未处理请求,然后重试
Thank you.