定义
一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利用,还能防止过分调度。
线程池参数
corePoolSize - 核心线程数
maximumPoolSize - 最大线程数
keepAliveTime - 当线程数大于核心线程数时,多余线程等待新任务的最大空闲时间
unit
workQueue - 保存任务的线程队列
threadFactory - 声明一个线程工厂,自定义的线程工厂可定制线程池名字以及创建的线程的名字等属性
RejectedExecutionHandler - 拒绝策略,默认的策略是抛出异常
拒绝策略类型
抛异常 - AbortPolicy
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
throw new RejectedExecutionException("Task " + r.toString() +" rejected from " +e.toString());
}
抛弃任务 - DiscardPolicy
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {}
抛弃最旧任务 - DiscardOldestPolicy
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
if (!e.isShutdown()) {
e.getQueue().poll();
e.execute(r);
}
}
直接同步运行线程,而不通过线程池执行 - CallerRunsPolicy
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
if (!e.isShutdown()) {
r.run();
}
}
线程池好处
降低资源消耗 通过重复利用已创建的线程,降低创建和销毁线程造成的系统资源消耗
提高响应速度 当任务到达时,任务可以不需要等到线程创建就能立即执行
提高线程的可管理性 线程是稀缺资源,如果过多地创建,不仅会消耗系统资源,还会降低系统的稳定性,导致使用线程池可以进行统一分配、调优和监控
Java自带线程池分析
newFixedThreadPool
创建声明
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
主要问题
阻塞队列是LinkedBlockingQueue,其队列大小为Integer.MAX_VALUE,有内存溢出风险
newCachedThreadPool
创建声明
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Run