核心接口: ExecutorService
核心实现类: ThreadPoolExecutor
创建一个指定工作线程数的线程池,其中参数 corePoolSize 和 maximumPoolSize 相等,
阻塞队列基于LinkedBlockingQueue,具有线程池提高程序效率和节省创建线程时所耗的开销的优点。
但是在线程池空闲时,即线程池中没有可运行任务时,它也不会释放工作线程,还会占用一定的系统资源;
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory);
}
初始化的线程池中只有一个线程,如果该线程异常结束,会重新创建一个新的线程继续执行任务,
唯一的线程可以保证所提交任务的顺序执行,
内部使用LinkedBlockingQueue作为阻塞队列
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory));
}
创建一个可缓存工作线程的线程池,默认存活时间60秒,线程池的线程数可达到Integer.MAX_VALUE,即2147483647,
内部使用SynchronousQueue作为阻塞队列;
在没有任务执行时,当线程的空闲时间超过keepAliveTime,则工作线程将会终止,
当提交新任务时,如果没有空闲线程,则创建新线程执行任务,会导致一定的系统开销
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(),
threadFactory);
}
初始化的线程池可以在指定的时间内周期性的执行所提交的任务,在实际的业务场景中可以使用该线程池定期的同步数据
public static ScheduledExecutorService newScheduledThreadPool(
int corePoolSize, ThreadFactory threadFactory) {
return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
}
public ScheduledThreadPoolExecutor(int corePoolSize,
ThreadFactory threadFactory) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
new DelayedWorkQueue(), threadFactory);
}
//创建线程池
private final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize,
keepAliveTime, unit, new LinkedBlockingQueue<>(), new ThreadPoolExecutor.AbortPolicy());
public ThreadPoolExecutor(int corePoolSize,//核心线程数
int maximumPoolSize,//最大线程数
long keepAliveTime,//空闲线程存活时间
TimeUnit unit,//空闲线程存活时间单位
BlockingQueue<Runnable> workQueue,//任务队列
ThreadFactory threadFactory,//创建线程的工厂
RejectedExecutionHandler handler//拒绝策略)
【两个考虑点:cpu io】
【CPU密集】 大部分场景是纯CPU计算,本质是要提升CPU的利用率,考虑CPU在多线程之间切换耗时
(线程等待时间+线程CPU时间)/线程CPU时间*CPU数目*利用率
举例:【4核CPU】
任务 任务执行时间 分配线程
500 0.2
1 / 0.2 = 5*4=20*利用率(0.8)=16个线程
等待时间占比越高,需要越多线程。
【IO密集】 IO操作时间相当于CPU计算时间非常长,要将硬件的性能发挥到一致
最佳线程数:IO耗时/CPU耗时+1
本节完~~