线程池: 数据源DataSource Druid
为何采用线程池?
-方便管理、监控线程状态
-提高任务响应速度
-线程可以重复利用
//1.加载驱动
//2.获取连接
//3.Statement
-select executeQuery():ResultSet
-update inserte delete executeUpdate():int
//3.ResultSet
//4.关闭资源
ExecutorService:普通调度池核心接口
-submit(Runnable || Callable) : Future<V>
-execute(Runnable) : void
ScheduledExecutorService:定时调度池(执行定时任务)
ThreadPoolExecutor:线程池核心实现类
Executors:线程池工具类
线程池工作流程:当任务到达线程池时工作顺序
-核心线程池corePoolSize
-阻塞队列BlockingQueue
-最大线程池maxiumPoolSize
-拒绝策略rejectHandler
1.若核心池未满,则创建新的线程执行任务而后将此线程入核心池
-若核心池满且有空闲线程,调度空闲线程执行任务。
2.将任务置入阻塞队列,排队等待空闲线程调度(juc)
-ArrayBlockingQueue:基于数组的有界阻塞队列
-LinkedBlockingQueue:基于链表的*阻塞队列
-SynchrousQueue:不存储元素的*阻塞队列
3.当阻塞队列满时,若此时最大线程池未满,创建新线程执行任务而后置入最大线程池中
4.若最大线程池已满,调用相应拒绝策略处理任务(默认为抛出异常且不处理任务)
手工创建线程池 new ThreadPoolExecutor()
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue)
Thread 类执行Callable FutureTask
FutureTask类保证多线程场景下任务只会被执行一次
Future get()会阻塞当前线程直到取得Callable的返回值
jdk内置四大线程池
固定大小线程池:LinkedBlockingQueue
应用场景:开启一个线程是有开销的,每一个用户都是一个servlet,每个servlet都是一个线程,
当服务器负载较重的时候,限制线程的数量,可以采用固定大小线程池
单线程池 ,当任务到达的时候,都进入LinkedBlockingQueue
应用场景:某些需要同步处理的场合(任务需要按序处理)
缓存线程池 应用场景