在实际开发工作中,如果并发的线程过多,并且每个线程执行一下就结束了,如此频繁的创建销毁线程,非常消耗时间并降低系统效率;因为引入线程池。
ThreadPoolExecutor
ThreadPoolExecutor是线程池的核心类,其构造函数中的参数如下:
- corePoolSize--核心池大小;默认情况下,初始化时线程池创建0个线程,当有任务时才创建线程,直到数量达到corePoolSize,任务将保存到阻塞队列中
- maximunPoolSize--表示线程池能创建的最大线程数
- keepAliveTime--表示空闲线程多久时间会销毁;默认只有当线程数大于corePoolSize时才有效,直到数量不超过corePoolSize,如果调用allowCoreThreadTimeOut(boolean),则全部有效,直到数量为0
- unit
- workQueue--设置阻塞队列类型
- threadFactory--创建线程工厂
- handler--当线程数达到maximunPoolSize时,后面的任务全部拒绝,该参数用于设置拒绝策略
线程池实现原理
线程池状态
- RUNNING-0,初始化时线程处于运行中的状态
- SHUTDOWN-1,当执行shutdown时,线程池不会立马关闭,而是不接受新的任务,等队列中的任务执行完后,然后关闭线程池
- STOP-2,当执行shutdownnow,立马关闭线程池,队列不接受任务,清空队列,并尝试中断正在执行的任务
- TERMINAL-3,SHUTDOWN和STOP,线程被销毁以及队列中的任务全部清空或被执行后,状态转为TERMINAL
任务的执行
- 初始化时,默认线程池中的线程数为0,当任务进来后,开始创建线程(阻塞队列自动查询队列中的任务)
- 当线程数达到corePoolSize时,后面进来的任务将被保存到队列中
- 当队列已满,继续创建新的线程,数量达到maximunPoolSize后,采用拒绝策略
- 当线程空闲后,根据keepAliveTime进行销毁直到数量不超过corePoolSize
队列类型以及排队策略
- ArrayBlockingQueue--先进先出,需要设置初始化的数组长度
- LinkedBlockingQueue--先进先出,默认长度为Integer.MAX_VALUE
- SynchronuosQueue--不保存任务,直接新建线程执行
任务拒绝策略
当线程数达到maximunPoolSize,还有任务进来则执行拒绝策略
- AbortPolicy,丢弃任务抛出异常
- DiscardPolicy,丢失任务不抛异常
- DiscardOldestPolicy,丢弃队列最前面(时间最久)的任务
- CallerRunsPolicy,由调度线程处理
常用线程池
- newFixedThreadPool,corePoolSize与maximunPoolSize数量相等,使用LinkedBlockingQueue
- newSingleThreadExecutor,corePoolSize与maximunPoolSize都为1,使用LinkedBlockingQueue
- newCacheThreadPool,corePoolSize为0,maximunPoolSize为Integer.MAX_VALUE,使用SynchronuosQueue