关于线程池的一些事情
今天就主要说一下面试的时候关于线程池最常问的几个问题
三大方法
关于创建线程池的三个方法,
ExecutorService pool = Executors.newSingleThreadExecutor();//单个线程
ExecutorService pool1 = Executors.newFixedThreadPool(5);//创建一个固定大小的线程池
ExecutorService pool2 = Executors.newCachedThreadPool();//可伸缩的线程池大小
七大参数
对于创建线程池,阿里巴巴开发手册不允许使用Executors来进行创建,因为这可能会导致内存溢出,强烈建议使用ThreadPoolExecutor来创建,其实从源代码可以看出,Executors创建线程池底层其实还是ThreadPoolExecutor来创建的,因此我们最好直接使用这个来创建,理解里面的具体含义
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), handler);
}
从源代码可以看见这七个参数:
corePoolSize:核心线程池大小
maximumPoolSize:最大线程池大小
keepAliveTime:超时了没有线程进来就会被释放
unit:超时单位
workQueue:阻塞队列
ThreadFactory:线程工厂。创建线程的,一般不用动
handler:拒绝策略
四种拒绝策略
对于线程数目很多,阻塞队列已经满了,超过了最大线程数,又进来了任务,针对这种情况,有四种拒绝策略
1:new ThreadPoolExecutor.AbortPolicy() //若线程数超过最大线程数,不会处理最大线程数后面的,
//其他的进入阻塞队列,超过(最大线程数+阻塞队列容量)抛出异常
2:new ThreadPoolExecutor.CallerRunsPolicy()// 从哪里来的回到哪里去
3:new ThreadPoolExecutor.DiscardPolicy()// 阻塞队列满了不会抛出异常,丢掉任务
4:new ThreadPoolExecutor.DiscardOldestPolicy() //队列满了,尝试和最早的竞争,也不会抛出异常
这就是面试关于线程池常问的