之前简单介绍了下BlockingQueue也算是为本文做了一个前置铺垫了,今天就来介绍下线程池,因为如果每个线程任务都要显示的手动创建的话会大大浪费资源,所以用线程池来统一维护线程的生命周期;下面先介绍了解线程池需要提前知道的相关类或接口;
前置类或接口
Executor
线程调度的顶层接口,就定义了一个可以执行线程的execute方法,方法描述如下:void execute(Runnable command);
ExecutorService
Executor的子类之一,定义了线程的一系列生命周期方法;如:
- void shutdown(); 将线程池的状态设为SHUTDOWN,表示关闭线程池停止线程池接收新任务,非阻塞式的调用,已经执行的任务会继续执行
- boolean awaitTermination(long timeout, TimeUnit unit) 阻塞式的shutdown,等所有线程都执行完毕返回
- List
shutdownNow();
将线程池的状态设置STOP,并试图停止所有正在执行的任务,将正在等待的任务列表返回;需要注意的是本方法尝试停止正在执行的线程所用的方法是Thread.interrupt(),而这种方法并不能保证一定能停止线程,所以调用了shutdownNow并不是字面意思一样马上退出线程池,有可能也是需要等所有任务都执行完了才退出 - boolean isTerminated(); 如果shutdown后所有的任务都已完成返回true,需要注意的是如果不调用shutdown方法本方法永远不会返回true
- boolean isShutdown();线程池被关闭返回true
- Future<?> submit(Runnable task);表示提交一个任务并执行,并且有返回值
- void execute(Runnable command); 是其父类Executor的方法,也表示执行一个任务,但是没有返回值
线程池 ThreadPoolExecutor
快速使用
七个构造参数
- 核心线程数(corePoolSize)
无论是否空闲都会在线程池中活跃的线程数,除非设置了allowCoreThreadTimeOut参数 - 最大线程数(maximumPoolSize)
线程池内允许存在的最大线程数,包括核心线程数 - 允许的空闲时间(keepAliveTime)
线程空闲多久会被回收 - 空闲时间的单位(unit)
线程等待被回收的时间单位 - 任务队列(workQueue)
BlockingQueue的各种实现,用来接收等待线程池执行的任务 - 线程工厂(threadFactory)
线程Thread的定义工厂,可实现ThreadFactory接口来自定义,也可以使用JDKK自带的线程工厂 - 拒绝策略(handler)
可以实现RejectedExecutionHandler接口自定义拒绝策略,JDK默认提供四种实现:
-- AbortPolicy 直接抛弃并抛异常(线程池默认拒绝策略)
-- DiscardPolicy 直接抛弃任务不执行也不抛异常
-- DiscardOldestPolicy 抛弃队列中最老的任务,然后重试execute方法,除非执行器被关闭任务才会被丢弃。
-- CallerRunsPolicy 由调用execute的线程执行该任务,除非执行器被关闭任务才会被丢弃。