1.线程池介绍
(1)降低系统资源消耗,通过重用已存在的线程,降低线程创建和销毁造成的消耗;
(2)提高系统响应速度,当有任务到达时,通过复用已存在的线程,无需等待新线程的创建便能立即执行;
(3)方便线程并发数的管控。因为线程若是无限制的创建,可能会导致内存占用过多而产生OOM,并且会造成cpu过度切换(cpu切换线程是有时间成本的(需要保持当前执行线程的现场,并恢复要执行线程的现场))。
(4)提供更强大的功能,延时定时线程池。
2.核心类:
ThreadPoolExecutor
3.参数:
- int corePoolSize:核心线程数 ->当前线程小于核心线程数时,自动创建新的线程
- int maximumPoolSize:允许最大线程数
- long keepAliveTime:线程空闲时,存货时间
- TimeUnit unit:时间单位
- BlockingQueue<Runnable> workQueue:保存任务的阻塞队列
RejectedExecutionHandler handler:饱和策略:
①AbortPolicy(默认):直接抛出异常
②CallerRunsPilicy:用调用者所在的线程执行任务
③DiscardOldestPolicy:丢弃队列中最老的任务
④DiscardPolicy:直接丢弃当前任务
··实现饱和策略只需要实现RejectedExecutionHandler接口
4.常用方法
- perstartAllCoreThreads():会一次性创建corePoolSize个数的线程数
- execute(Runnable command) 提交线程池 无返回值
- Future<T> submit(Callable<T>task) 提交线程池 有返回值
- shutdown():设置线程池状态,只中断没有执行的线程
- shutdownNow():设置线程池状态,尝试终止正在运行和阻塞的线程。
5.合理配置线程池线程数量
获取CPU核心数的方法:Runtime.getRuntime.availableProcessors()
计算密集型:线程数小一些,最大推荐CPU核心数+1, +1的原因防止页缺失
IO密集型(读取文件、数据库连接、网络通讯):线程数适当大一些,CPU核心数*2
6.预定义线程池
Executors.newFixedThreadPool(int nThreads)
(1)
适用:创建固定的线程数量,适用负载较重的服务器,使用了无界队列,线程空闲就会被杀掉
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
(2)
适用:创建单个线程,需要保证顺序执行的任务,不会有多个线程活动,使用了无界队列
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
(3)
适用:根据需要创建新线程,适合短期异步的任务
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
(4)
适用:IO密集型
public static ExecutorService newWorkStealingPool() {
return new ForkJoinPool
(Runtime.getRuntime().availableProcessors(),
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null, true);
}
(5)
适用:需要执行定期执行任务。
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
(6)
适用:单线程定期执行任务,保证顺序执行任务。
public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
return new DelegatedScheduledExecutorService
(new ScheduledThreadPoolExecutor(1));
}
方法:
- schedule:只执行一次,可以延时执行。
- scheduleAtFixedRate:提交固定时间间隔的任务。
- scheduleWithFixedDelay:提交固定时间延时间隔任务。