1、看一下几个常见的线程池:
ExecutorService threaPool = Executors.newFixedThreadPool(5);//一池5个处理线程
ExecutorService threaPool = Executors.newSingleThreadExecutor();//一池1个处理线程
ExecutorService threaPool = Executors.newCachedThreadPool();//一池N个处理线程
// 1、newFixedThreadPool(),源码
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue());
}
// 看一下 new LinkedBlockingQueue<>() 阻塞队列构造方法
public LinkedBlockingQueue() {
this(Integer.MAX_VALUE);//阻塞队列的大小是:Integer.MAX_VALUE
}
//2、newSingleThreadExecutor(),源码
//核心线程 = 最大线程数 = 1,也是linkedBlockingQueue---链表结构组成的有界队列
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue()));
}
//3、newCatchThreadPool(),源码
// Integer.MAX_VALUE 个最大线程数,SynchronousQueue(同步队列)
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue());
}
//使用
try{
for(int i=1 ; i<=10;i++){
threaPool.execute(()->{
System.out.println(Thread.currentThread().getName()+" \t 办理业务 ");
});
}
}catch(Exception e){
e.printStackTrace();
}finally {
threaPool.shutdown();
}
ExecutorService 提供的线程池 一般是 等待队列 的长度 线程的个是 = Integer.MAX_VALUE,创建大量线程,一般情况下都是根据自己的业务 自定义线程池;
2、自定义线程池;
//线程池 参数配置(根据服务器核数来)
int corePoolSize = (int) (Runtime.getRuntime().availableProcessors() / (1-0.9));
int maximumPoolSize = corePoolSize * 10;//或者 * 20
int keepAliveTime = 5;
int WORK_QUEUE_SIZE = 1000;//根据自己的机器性能 压测,调节到可以接受的大小
ExecutorService pool = new ThreadPoolExecutor(corePoolSize, maximumPoolSize,
keepAliveTime, TimeUnit.SECONDS, new LinkedBlockingDeque(WORK_QUEUE_SIZE),
Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());
//拒绝策略
ExecutorService pool1 = new ThreadPoolExecutor(corePoolSize, maximumPoolSize,
keepAliveTime, TimeUnit.SECONDS, new LinkedBlockingDeque(WORK_QUEUE_SIZE),
Executors.defaultThreadFactory(),new RejectedExecutionHandler() {
//拒绝策略
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
/**
* 自己处理 多余的线程
* 写到mq中再处理一遍
* 记录一下,用定时来跑
*/
}
});
/**
源码参数整理:
corePoolSize:核心线程数(初始线程数---个人理解)
maximumPoolSize:最大线程数
keepAliveTime:线程的存活时间
unit:存活时间单位
workQueue:阻塞队列
threadFactory:创建线程的工程
handler:拒接策略(下面介绍)
*/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
3、线程池原理:
新建线程池,初始化corePoolSize个线程,往execute中提交认为,当任务数达到corePoolSize个,放到BlockIngQueue阻塞队列中。如果阻塞队列慢啦,就新加线程到maxmumPoolSize个,从阻塞队列中获取任务 处理;
如果请求数减少,线程超过keepAliveTime的存活时间,线程会慢慢的被回收到corePoolSize个;
如果请求数还是增多,就会启用拒绝策略
RejectedExecutionHandler
4中拒绝策略
RejectedExecutionHandler 接口的实现类。
拒绝策略源码
:DiscardOldestPolicy 丢齐等待时间最长的任务(取出第一个任务,插入新的任务)
:DiscardPolicy:不处理(丢弃)
:CallerRunsPolicy:返回到当前线程
AbortPolicy:抛出异常 rejectedExecutionException(默认)