我们知道,使用线程池的好处有:降低资源的消耗、提高响应的速度,方便我们对象线程进行管理.下面将从线程的3大方法,7大参数、4中拒绝策略纤细介绍:
一、三大方法
1、线程池中只有单个线程在执行
ExecutorService threadExecutor = Executors.newSingleThreadExecutor();
2、线程池中规定只有固定的个数的线程在执行 ExecutorService threadExecutor = Executors.newFixedThreadPool(5);
3、可伸缩的 遇强则强 遇弱则弱
ExecutorService threadExecutor = Executors.newCachedThreadPool();
通过查看源码发现,这个三个方法的本质都是new ThreadPoolExecutor();
二、7大参数
corePoolSize: 核心线程池大小
maximumPoolSize:最大核心线程池大小
keepAliveTime:超时了就没人调用就会释放
TimeUnit:超时的单位
BlockingQueue:阻塞队列
ThreadFactory:线程工厂,用于创建线程的,一般不用动
RejectedExecutionHandler:拒绝策略
在阿里巴巴开发手册中,不建议使用Executors工具类创建,避免造成OOM;
三、4种拒绝策略
均为ThreadPoolEexcutor中的静态内部类
1、线程池的默认拒绝策略为AbortPolicy,即丢弃任务并抛出RejectedExecutionException异常(即后面提交的请求不会放入队列也不会直接消费并抛出异常);
2、ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务(不会丢弃任务,最后所有的任务都执行了,并不会抛出异常),一般都是由朱主线程去执行
3、ThreadPoolExecutor.DiscardPolicy
丢弃任务,但是不抛出异常。如果线程队列已满,则后续提交的任务都会被丢弃,且是静默丢弃(也不会抛出任何异常,任务直接就丢弃了)。4、ThreadPoolExecutor.DiscardOldestPolicy
丢弃队列最前面的任务,然后重新提交被拒绝的任务(丢弃掉了队列最前的任务,并不抛出异常,直接丢弃了)。
四、思考
1、最大线程数该如何定义?
- CPIU密集型:几核的CPU奥就是几,保证CPU的效率最高
- IO密集型:程序中会存在大量的 I/O 操作占用时间,导致线程空余时间很多,所以通常就需要开CPU核心数两倍的线程