一、线程池是什么
def:是一种池化思想管理线程的工具,因为线程过多会带来额外的开销,比如线程的创建,线程的销毁,线程的调度。
线程池维护多个线程,分配可并发的任务,避免创建销毁线程带来的开销,也避免了线程过多导致的过分调度问题。
线程池带来的好处如下:
- 降低资源消耗,增加可管理性:使用池化技术,减少创建销毁线程带来的消耗,另一方面可以限制线程创建数量,避免过分调度
- 提高响应速度:任务到达时,无需创建线程即刻执行
- 提供额外的功能:提供了延时和定时线程池ScheduledThreadPoolExecutor
其他池化思想
内存池(Memory Pooling):预先申请内存,提升申请内存速度,减少内存碎片。
连接池(Connection Pooling):预先申请数据库连接,提升申请连接的速度,降低系统的开销。
实例池(Object Pooling):循环使用对象,减少资源在初始化和释放时的昂贵损耗。
二、线程池是怎么实现的
基于JDK1.8的threadPoolExecutor继承关系
1、Executor 可以将任务的提交和每个任务运行的细节(线程使用调度)解耦
开发者只需要提供runnable对象即可
public interface Executor {
void execute(Runnable command);
}
2、扩充执行任务能力,补充可异步执行任务的future方法
提供终止线程池的方法shutdown允许先前提交的任务在终止之前执行;shutDownNow会尝试停止只在执行和等待执行的任务
public interface ExecutorService extends Executor {
void shutdown();
List<Runnable> shutdownNow();
boolean isShutdown();
boolean isTerminated();
boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException;
<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
Future<?> submit(Runnable task);
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException;
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException;
<T> T invokeAny(Collection<? extends Callable<T>> tasks)
throws InterruptedException, ExecutionException;
<T> T invokeAny(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
3、而threadPoolExecutor一方面管理自身的生命周期,另一方面管理线程和任务。
线程池内部的构建了一个生产者消费者模型,任务管理是生产者,当任务提交后线程池会判断任务是直接执行;还是放到缓存队列;还是直接拒绝任务,这个时机可以看上篇JAVA并发编程-线程池源码解读(一);线程管理是消费者,根据任务请求进行任务分配,当线程执行完任务后会继续获取新的任务执行,当获取不到任务的时候,线程会被回收(具体细节需要参考是否是核心线程,allowCoreThreadTimeout属性等)。