- 异步任务提交执行架构
- 类关系图
-
- 示例:线程池提交Runnable任务
-
- 示例:线程池提交Callable任务
-
- Executor 线程提交接口
Executor(Runnable c):将Runnable任务提交到线程池中
-
- ExecutorService 线程池接口
- 提交异步任务方法:
- ExecutorService 线程池接口
- execute(Runnable c): 向线程池中提交任务。
- Future<?> submit(Runnable task) <T> Future<T> submit(Callable<T> task)
向线程池中提交任务。区别在于Runnable在执行完毕后没有结果,Callable执行完毕后有一个结果。相同点在于都返回一个Future对象(可以阻塞线程直到运行完毕,也可以取消任务执行,也能够检测任务是否被取消或者是否执行完毕)。
-
-
- execute() submit()的区别
-
Executor()的入参可以为Runnable以及Callable对象,同时又返回值;
当外部需要对线程抛出的异常进行捕获处理时,使用submit()方式提交,客通过Future.get()捕获。
-
- ScheduledExecutorService 定时调度接口
和Timer/TimerTask类似,用于解决重复执行的任务
-
- ThreadPoolExecutor 线程池类
- 构造方法1
- ThreadPoolExecutor 线程池类
keepAliveTime:当线程数大于core数,那么超过该时间的线程将会被终结。
workQueue若线程池已经被占满,则该队列用于存放无法再放入线程池中的Runnable。
-
-
- 构造方法2
-
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler)
其中handler表示线程池对拒绝任务的处理策略。
-
-
- 使用注意事项
-
若线程池中的线程数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。
若线程池中的线程数量等于corePoolSize且缓冲队列workQueue未满,则任务被放入缓冲队列。
若线程池中线程的数量大于corePoolSize且缓冲队列workQueue满,且线程池中的数量小于maximumPoolSize,则建新的线程来处理被添加的任务。
若线程池中线程的数量大于corePoolSize且缓冲队列workQueue满,且线程池中的数量等于maximumPoolSize,那么通过handler所指定的策略来处理此任务。
当线程池中的线程数量大于corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止。
-
- Executors 工厂
提供静态方法,用于创建ExecutorService线程池,其实质调用的是ThreadPoolExecutor的构造器。
-
-
- 单线程的线程池newSingleThreadExecutor(...)
-
这个线程池只有一个线程在工作,在线程处理完一个任务后接着处理下一个任务,若该线程出现异常,将会有一个新的线程来替代。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。
-
-
- 创建固定大小的线程池 newFixedThreadPool(...)
-
每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小,达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。
-
-
- 可根据需要创建新线程的线程池 newCachedThreadPool(...)
-
当线程池大小超过了需要处理任务需要的线程时,会自动回收空闲线程(60秒)。当任务增加时,会自动的添加新的线程来处理,线程池的大小取决于jvm能创建的最大线程的大小。容易导致内存不足。
-
-
- 大小不限的定时调度的线程池 newScheduledThreadPool(...)
-
创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。
-
-
- 单线程的定时调度的线程池newSingleThreadScheduledExecutor()
-
创建一个使用单个 worker 线程的 Executor,以无界队列方式来运行该线程,并在需要时使用提供的 ThreadFactory 创建新线程。
-
- 线程池的生命周期
- 启动线程池
- 线程池的生命周期
线程池被构造完成之后,进入可运行状态;在接到任务后,进入运行状态。
-
-
- 关闭线程池
- shutdown():平缓的关闭线程池。
- 关闭线程池
-
线程池停止接受新的任务,同时等待已经提交的任务执行完毕,包括那些进入队列还没有开始的任务。shutdown()方法执行过程中,线程池处于SHUTDOWN状态。
-
-
-
- shutdownNow():立即关闭线程池。
-
-
线程池停止接受新的任务,取消所有执行的任务和已经进入队列但是还没有执行的任务。
shutdownNow()方法执行过程中,线程池处于STOP状态。
shutdownNow方法本质是调用Thread.interrupt()方法(让线程处于interrupted状态,并不会让线程真正的停止)。线程中必须要有处理interrupt事件的机制才能停止线程。
-
-
- 线程池结束TERMINATED
-
即shutdown()或者shutdownNow()执行完毕,线程池就结束了(terminated)。
isTerminating() 如果关闭后所有任务都已完成,则返回 true。
isShutdown() 如果此执行程序已关闭,则返回 true。