线程池
三大方法
我们先看使用Executors创建的三种线程池
1 | Executors.newSingleThreadExecutor();//创建一个只有一个线程的线程池 |
执行线程
1 | public static void main(String[] args) { |
七大参数
阿里巴巴规范中有这么一条
1 | 线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。 说明:Executors返回的线程池对象的弊端如下: |
我们来看看创建这三种线程池的构造方法
1 | public static ExecutorService newSingleThreadExecutor() { |
可以发现,这三个构造方法创建的对象其实都是ThreadPoolExecutor对象,只不过就是构造参数不一样。
参数 | 作用 |
---|---|
int corePoolSize | 核心线程池的大小 |
int maximumPoolSize | 最大线程池的大小 |
long keepAliveTime | 超时时间过后就释放 |
TimeUnit unit | 超时时间单位 |
BlockingQueue< Runnable> workQueue | 阻塞队列 |
ThreadFactory threadFactory | 线程工厂,创建线程的,一般不用动 |
RejectedExecutionHandler handler | 拒绝策略 |
1 | public ThreadPoolExecutor(int corePoolSize, |
corePoolSize为一直开着的线程数,当workQueue已经满了,则继续开启线程直到maximumPoolSize,当线程数到了maximumPoolSize,然后workQueue也满了,如果还有新的任务,则使用handler拒绝策略对其进行处理。
当corePoolSize-maximumPoolSize区间的线程等待了workQueue时间后,还是没任务来,则关闭该区间的线程
1 | ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( |
CPU密集型和IO密集型
最大线程数到底如何定义?
CPU密集型
几核CPU就是几,可以保证效率最高
1 | Runtime.getRuntime().availableProcessors()//动态获取cpu核数 |
IO密集型
程序里面有多少个非常消耗IO的线程,一般最大线程数设置为该数字的两倍
四大拒绝策略
AbortPolicy
不处理此任务,并且抛出异常
CallerRunsPolicy
不处理此任务,往上传递此任务,哪来的回哪里去
DiscardOldestPolicy
不处理此任务,不会抛出异常
DiscardPolicy
尝试和最老的那一个线程竞争,不会抛出异常