本文总结一下线程池是怎么回事
第一部分:线程池类的结构
线程池存在于Java的并发包J.U.C中,线程池可以根据项目灵活控制并发的数目,避免频繁的创建和销毁线程,达到线程对象的重用。
下面是线程池的类图:
1、 接口Executor
接口Executor中,只有一个方法,为execute()
2、 接口ExecutorService,继承自Executor
几个重要的方法:
(1) 关闭线程池的方法,有两种
一个ExecutorService(J.U.C)可以关闭,这将导致它拒绝新的任务。 ExecutorService的两种关闭线程池的方式,shutdown和shutdownNow方法:
① shutdown():拒收新的任务,立马关闭正在执行的任务,可能会引起报错,需要异常捕获
② shutdownNow():拒收新的任务,等待任务执行完毕,要确保任务里不会有永久等待阻塞的逻辑,否则会导致线程关闭不了
③ 不是马上关闭,要想等待线程池关闭,还需要调用waitFermination来阻塞等待
④ 还有一些业务场景下,需要知道线程池中的任务是否全部执行完成,当我们关闭线程池之后,可以用isTerminated来判断所有的线程是否执行完成,千万不要用isShutdown, 它只是返回你是否调用过shutdown的结果
(2) submit()方法
方法submit延伸的方法Executor.execute(Runnable)通过创建并返回一个Future可用于取消执行和/或等待完成。submit()与execute()的一个区别是submit()有返回值,并且能够处理 异常
3、 Executors(J.U.C),提供了6个静态方法,分别创建6种不同的线程池,六大静态方法 内部都是直接或间接调用ThreadPoolExecutor类的构造方法创建线程池对象,这六个静态方法 本身是没有技术含量的。
下面介绍常用的四种:
(1)FixedThreadPool
FixedThreadPool的特点:固定池子中线程的个数。使用静态方法newFixedThreadPool()创建线程池的时候指定线程池个数。
(2)CachedThreadPool(弹性缓存线程池)
CachedThreadPool的特点:用newCachedThreadPool()方法创建该线程池对象, 创建之初里面一个线程都没有,当execute方法或submit方法向线程池提交任务时, 会自动新建线程;如果线程池中有空余线程,则不会新建;这种线程池一般最多情况可 以容纳几万个线程,里面的线程空余60s会被回收。
(3)SingleThreadPool(单线程线程池)
SingleThreadPoo