JUC笔记:线程池⚡
前言
本文主要是通过狂神juc学习之后整理归纳的笔记
感谢狂神的视频教学。
一、线程池的三大方法
使用Executors创建线程池存在三种方法:
创建一个固定大小的线程池
ExecutorService threadPool = Executors.newFixedThreadPool(5);//创建一个固定大小的线程池
创建一个只存在单个线程的线程池
ExecutorService threadPool1 = Executors.newSingleThreadExecutor();//单个线程
创建一个自动伸缩的线程池,可以自动调节线程池的大小。
ExecutorService threadPool2 = Executors.newCachedThreadPool();//可伸缩的线程池
二、ThreadPoolExecutor
虽然Executors创建线程池十分方便,但是却不被推荐。
阿里的开发手册中强调,创建线程池不要使用Executors创建,使用ThreadPoolExecutor创建。实际开发中一定是使用后者进行开发。
1.七大参数
源码如下:
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;
}
可以看见,源码中存在七个可以设置的参数来生成线程池。
分别是:
- int corePoolSize,//核心线程池大小
- int maximumPoolSize,//最大核心线程池大小
- long keepAliveTime,//超时了没人用调用就会释放
- TimeUnit unit,//超时单位
- BlockingQueue workQueue,//阻塞队列
- ThreadFactory threadFactory,//线程工厂,一般不做修改
- RejectedExecutionHandler handler//拒绝策略
2.银行例子说明
在银行办理业务时存在以下场景:
普通情况下只会打开两个业务窗口,新来的顾客会在候客厅等着,但是当候客厅满了,银行就会打开剩下的窗口进行服务。
可以见得,1、2窗口即是核心线程池大小;1、2、3、4、5即是最大线程池大小;候客厅就是阻塞队列。当阻塞队列满了,就会启动最大线程池大小。
如果,最大线程情况下,候客厅满了,但是任然有顾客前来,此时就会采取拒绝服务,也就是我们的拒绝策略。
3. 四大拒绝策略
四大拒绝策略分别是:
new ThreadPoolExecutor.AbortPolicy()//抛出异常策略
new ThreadPoolExecutor.CallerRunsPolicy()//哪里来的去哪里
new ThreadPoolExecutor.DiscardPolicy()//队列满了,丢到任务,不会抛异常
new ThreadPoolExecutor.DiscardOldestPolicy()//队列满了,尝试和最早的竞争,不会抛出异常
总结
以上就是今天要讲的内容,本文讲解了JUC中线程池的创建,以及使用ThreadPoolExecutor闯将线程池时需要设置的相关参数。希望对大家了解线程池有所帮助。