转自:http://www.spring4all.com/article/1365
目录
- 常用线程池列表
- ThreadPoolExecutor
- ThreadFactory线程工厂
- RejectedExecutionHandler拒绝策略
- Queue任务队列
一. 常用线程池列表
这部分内容,只是帮助你回顾一下线程池的知识,大家重点看方法内的实现
1、构造一个固定线程数目的线程池,配置的corePoolSize与maximumPoolSize大小相同,同时使用了一个无界LinkedBlockingQueue存放阻塞任务,因此多余的任务将存在再阻塞队列,不会由RejectedExecutionHandler处理
2、构造一个缓冲功能的线程池,配置corePoolSize=0,maximumPoolSize=Integer.MAX_VALUE,keepAliveTime=60s,以及一个无容量的阻塞队列 SynchronousQueue,因此任务提交之后,将会创建新的线程执行;线程空闲超过60s将会销毁
3、构造一个只支持一个线程的线程池,配置corePoolSize=maximumPoolSize=1,无界阻塞队列LinkedBlockingQueue;保证任务由一个线程串行执行
4、构造有定时功能的线程池,配置corePoolSize,无界延迟阻塞队列DelayedWorkQueue;有意思的是:maximumPoolSize=Integer.MAX_VALUE,由于DelayedWorkQueue是无界队列,所以这个值是没有意义的
二. ThreadPoolExecutor
相信大家从上面的众多线程池中都已经看到了这个类,因为上面的线程池底层的构造都是由这个类创建的,
那么我们就开始研究这个类
首先看一下构造方法,关于注释一定要好好看,每个参数都理解了,那么你就弄懂了
-
核心的线程池
-
最大线程池就是说你定义的线程池运行创建的最大线程数量
-
空闲时间回收,当这个时间后还没有任务执行就将线程回收
-
单位,控制上面时间的单位,可以为秒,或者分钟
-
核心线程都已经去执行任务但是,任务还有,那么久先放到这个队列里,就相当于集合
-
创建线程用户的线程工厂,里面只有一个方法就是newThread,你可以自定义线程名
-
拒绝策略,当任务已经执行不了,你拒绝的策略
上面的文字可能你看的不太明白,小编这里画了一个图,大家仔细看看
三. ThreadFactory
ThreadFactory有什么用呢? 其实就是一个接口,既然是线程工厂,那么肯定就是创建线程的了
接口就是这么简单,那么我们在开发中到底有什么实际用处呢? 下面是小编写的一个线程工厂,主要是在创建线程的时候
给当前线程分配名字和线程组方便控制。读到这里,有没有一点启发呢?
四. 拒绝策略
拒绝策略就是任务实在是已经执行不了,那么就需要你告诉程序,怎么样去拒绝在执行其他任务
ThreadPoolExecutor类里面是内置了4中拒绝策略,我们一个一个来分析
- 策略-1
用于被拒绝任务的处理程序,它直接在 execute 方法的调用线程中运行被拒绝的任务;如果执行程序已关闭,则会丢弃该任务。如下:
- 策略-2
直接抛出异常
- 策略-3
什么都不做直接丢弃
- 策略-4
从任务队列中移除最早的一个,然后将拒绝的任务重新执行
到这里拒绝策略就说完了,应该都明白了吧,下面我们说下实际中会怎么用。
如果在任务不是特别多特别重要的情境下,可以在执行拒绝策略发送一个通知事件,通知相关的人查看。
比如以下这种
但是当任务特别重要的时候,比如说银行处理用户的转账信息更新事物的任务时候,那么这个任务就比较重要了,不可能用这种的,这种对数据要求高的我们都是用Elastic-Job,这种分布式任务处理框架,任务会首先落数据库,然后从数据库中批量读取任务执行。感兴趣的童鞋可以下去自行了解。
五. 任务队列
扩展点知识,队列再次,小编不对队列进行讲解,只提到,感兴趣的童鞋下去在深入研究
Queue:
分为阻塞队列和非阻塞队里
阻塞队列一共有四套方法分别用来进行insert、remove和examine,当每套方法对应的操作不能马上执行时会有不同的反应,下面这个表格就分类列出了这些方法:
- ThrowsException:如果操作不能马上进行,则抛出异常
- SpecialValue:如果操作不能马上进行,将会返回一个特殊的值,一般是true或者false
- Blocks:如果操作不能马上进行,操作会被阻塞
- TimesOut:如果操作不能马上进行,操作会被阻塞指定的时间,如果指定时间没执行,则返回一个特殊值,一般是true或者false 需要注意的是,我们不能向BlockingQueue中插入null,否则会报NullPointerException。
- LinkedBlockingQueue 无边界队里
- PriorityBlockingQueue 排序队列,内部会排序但是要实现排序接口
- SynchronousQueue 同步队列
- ArrayBlockingQueue 阻塞队里,内不是数组,有边界
- DelayQueue 延迟队里