基本原理
线程池做的工作主要是控制运行的线程的数量,处理过程中将任务放入队列,然后在线程创建后启动这些任务,如果线程数量超过了最大数量超出数量的线程排队等候,等其它线程执行完毕, 再从队列中取出任务来执行。
主要特点:1.线程复用;2.控制最大并发数量;3.管理线程
1.降低资源消耗,通过重复利用已创建的线程来降低线程创建和销毁造成的消耗。13;2.提高相应速度,当任务到达时,任务可以不需要的等到线程创建就能立即执行。13;3.提高线程的可管理性,线程是稀缺资源,如果无限制的创建,不仅仅会消耗系统资源,还会降低体统的稳定性,使用线程可以进行统一分配,调优和监控。
构造方法
Executors
静态工厂类,提供了Executor、ExecutorService、ScheduledExecutorService、 ThreadFactory 、Callable 等类的静态工厂方法
Executors.newSingleThreadExecutor()
只有一个线程的线程池,因此所有提交的任务是顺序执行
Executors.newCachedThreadPool()
线程池里有很多线程需要同时执行,老的可用线程将被新的任务触发重新执行,如果线程超过60秒未执行,将被终止并从池中删除
Executors.newFixedThreadPool()
拥有固定线程数的线程池,如果没有任务执行,那么线程会一直等待
Executors.newScheduledThreadPool()
用来调度即将执行的任务的线程池
Executors.newWorkStealingPool()
能够合理的使用CPU进行对任务操作(并行操作),所以适合使用在很耗时的任务中
核心参数
maximumPoolSize
workQueue
任务队列,被提交但尚未被执行的任务
keepAliveTime
当前线程池数量超过 corePoolSize 时,多余的空闲线程的存活时间,即多次时间内会被销毁。
运行过程
1.当线程池小于corePoolSize时,新提交任务将创建一个新线程执行任务,即使此时线程池中存在空闲线程
2.当线程池达到corePoolSize时,新提交任务将被放入 workQueue 中,等待线程池中任务调度执行
3.当workQueue已满,且 maximumPoolSize 大于 corePoolSize 时,新提交任务会创建新线程执行任务
4.当提交任务数超过 maximumPoolSize 时,新提交任务由 RejectedExecutionHandler处理
5.当线程池中超过corePoolSize 线程,空闲时间达到 keepAliveTime 时,关闭空闲线程
6.当设置allowCoreThreadTimeOut(true) 时,线程池中 corePoolSize 线程空闲时间达到 keepAliveTime 也将关闭
配置线程池
CPU密集型任务
尽量使用较小的线程池,一般为CPU核心数+1。 因为CPU密集型任务使得CPU使用率很高,若开过多的线程数,会造成CPU过度切换。
IO密集型任务
可以使用稍大的线程池,一般为2*CPU核心数。 IO密集型任务CPU使用率并不高,因此可以让CPU在等待IO的时候有其他线程去处理别的任务,充分利用CPU时间。