线程池
任务多,时间短,为了减少创建和销毁线程.
可以使用线程池,预先创建部分线程,重复使用,减少线程池的开销.
jdk5以后java内置支持线程池.
ThreadPoolExecutor类.
是线程池中最核心的一个类.
提供了四个构造器:
构造器中各个参数的含义:
corePoolSize: 核心池的大小.创建了线程池后默认线程数为0,当线程数目达到corePoolSize后,就会将到达的线程放到缓存队列中; 当调用了prestartAllCoreThreads()或者prestartCoreThread()方法后(预创建线程),即在没有任务到来之前就创建corePool’Size个线程或者一个线程
maximumPoolSize:线程池最大线程数(线程池中最多能创建多少线程)
keepAliveTime:表示线程没有任务执行的时候最大保持多久会终止. 当线程中的线程数大于corePoolSize时,如果一个线程的空闲时间大于keepAliveTime时,则会终止.除非线程数小于corePoolSize.
unit:参数keepAliveTime的单位
workQueue:一个阻塞队列
threadFactory:线程工厂,用来创建线程
handler:表示当拒绝处理任务时的策略
线程池的执行
创建完ThreadPoolExecutor之后,当向线程提交任务时,通常使用execute方法.
- 如果核心线程存活的核心线程数小于线程数corePoolSize时,线程池会创建一个核心线程去执行任务.
- 如果线程数等于corePoolSize时,一个新的任务会被提交到WorkQueue队列等待.
- 如果线程数等于corePoolSize,而且WorkQueue队列也满了,判断线程数是否达到maximumPoolSize,如果没到达,创建一个非核心线程执行任务.
- 如果线程数达到maximumPoolSize,直接采用拒绝策略处理.
线程池中的队列
有以下几个队列:
ArrayBlockingQueue:
数组实现的有界阻塞队列
LinkedBlockingQueue:
基于链表结构的阻塞队列; newfixedThreadPool线程池使用这个队列
DelayQueue:
延迟队列; 是一个任务定时周期的延迟执行的队列;newScheduledThreadPool线程池使用这个队列
PriorityBlockingQueue:
优先级队列.具有优先级的无界阻塞队列
SynchronousQueue:
同步队列; 不存储元素的阻塞队列.每次插入要等到另一个线程调用移除操作.否则一直阻塞状态.newCachedThreadPool线程池使用这个队列.
线程池的拒绝策略
线程池最后的参数RejectExecutionHandle用于指定线程池的拒绝策略.
当请求不断过来时,系统处理不过来,就会采用拒绝策略.
默认有四种类型.
AbortPolicy 策略:直接抛出异常,阻止系统正常工作
CallerRunsPolicy 策略:只有线程池未关闭,该策略直接在调用者线程中,运行当前被丢弃的线程
DiscardOleddestPolicy 策略:丢弃最老的线程,也就是即将被执行的任务,并尝试再次提交被丢弃的任务
DiscardPolicy 策略:默默丢弃无法处理的线程,不予处理.
**异常处理:**Thread线程通过try–catch捕捉并处理
execute 与 submit 的区别
执行任务可以使用execute和submit方法.
注意区别:
execute比较适合不需要关注返回值的场景
submit比较适合需要关注返回值的场景
关闭线程池
关闭线程池可以调用shutdownNow和shutdown方法来实现.
shutdown:
调用时,系统不会接受新的任务,但也不会去强制终止正在执行和已经提交的任务
shutdownNow:
池可以调用shutdownNow和shutdown方法来实现.
shutdown:
调用时,系统不会接受新的任务,但也不会去强制终止正在执行和已经提交的任务
shutdownNow:
对正在执行的任务全部发出interrupt(),停止执行.对还未开始执行的任务全部取消,并且返回还没有开始的任务列表.