- 线程池管理器:用于创建并管理线程池,包括创建线程池,销毁线程池,添加新任务;
- 工作线程:线程池中线程,在没有任务时处于等待状态,可以循环的执行任务;
- 任务接口:每个任务必须实现的接口,以供工作线程调度任务的执行,它主要规定了任务的入口,任务执行完后的收尾工作,任务的执行状态等;
- 任务队列:用于存放没有处理的任务。提供一种缓冲机制。
-
线程在java中是一个对象,更是操作系统的资源,线程创建,销毁需要时间。如果创建时间+销毁时间 > 执行任务时间,就很不合算。
-
java对象占用堆内存,操作系统线程占用系统内存,根据JVM规范,一个线程默认最大栈大小是1M,这个栈空间是需要从系统内存中分配的。线程过多,会消耗很多的内存。
-
操作系统需要频繁切换线程上下文,影响性能。
线程池就是为了方便的==控制线程数量==。
- 是否达到核心线程数量?没达到,创建一个工作线程来执行任务。
- 工作队列是否已满?没满,则将新提交的任务存储在工作队列里。
- 是否达到线程池最大数量?没达到,则创建一个新的工作线程来执行任务。
- 最后,执行拒绝策略处理这个任务。
-
接口定义和实现类
类型 名称 描述 接口 Executor 最上层的接口,定义了执行任务的方法execute 接口 ExecutorService 继承了Executor接口,拓展了Callable、Future、关闭等方法 接口 ScheduleExecutorService 继承了ExecutorServeice接口,增加了定时任务相关的方法 实现类 ThreadPoolExecutor 基础,标准的线程池实现 实现类 ScheduleThreadPoolExecutor 继承了ThreadPoolExecutor,实现了ScheduleExecutorServce中相关定时任务的方法 -
Executors工具类
你可以自己实例化线程池,也可以用Executors创建线程池的工厂类,常用方法如下:
- ==newFixedThreadPool(int nThreads)==创建一个固定大小,任务队列容量无界的线程池。核心线程数=最大线程数
- newCacheThreadPool() 创建的是一个大小无界的缓冲线程池。它的任务队列是一个同步队列。任务加入到池中,如果池中有空闲线程,则用空闲线程执行,如无 则创建新线程执行。池中的线程空闲超过60秒,将被销毁释放。线程数随任务的多少变化。适用于执行耗时较小的异步任务。池的核心线程数=0,最大线程数=Integer.MAX_VALUE
- newSingleThreadExecutor() 只有一个线程来执行无界队列的单一线程池。该线程池确保任务被加入的顺序一个一个依次执行。当唯一的线程因任务异常中止时,将创建一个新的线程来继续执行后续的任务。与newFixedThreadPool(1)的区别在于,单一线程池的大小在newSingleThreadExecutor方法中硬编码,不能再改变的。
- newScheduledThreadPool(int corePooSize) 能定时执行任务的线程池,该线程池的核心线程数由参数指定,最大线程数=Integer.MAX_VALUE
-
计算型任务:cpu数量的1-2倍
-
IO型任务:相对比计算型任务,需要多一些线程,要根据具体的IO阻塞时长进行考量决定。
如tomcat中默认的最大线程数为:200
也可以考虑根据需要在一个最小数量和最大数量间自动增减线程数。
-
线程池如果是一个无界队列,那设置和不设置最大线程数都无所谓,因为设置最大线程数是当队列满了之后还有新任务提交,才会新建线程
-
线程池关闭(shutdown和shutdownNow区别)
- shutdown 追加的任务拒绝、已经运行的任务,会等任务执行完成再关闭
- shutdownNow 追加的任务拒绝、将正在运行的线程也会终止



