文章目录
- 1.ThreadPoolExecutor描述
- 2.四种线程池的使用
• 2.1.newSingleThreadExecutor
• 2.2.newCachedThreadPool
• 2.3.NewScheduledThreadPool
• 2.4.newFixedThreadPool
1.ThreadPoolExecutor描述
ThreadPoolExecutor是一个 ExecutorService,它使用可能的几个池线程之一执行每个提交的任务,通常使用 Executors 工厂方法配置。
ThreadPoolExecutor主要的参数详解
参数名 | 描述 |
poolSize | 线程池中正在执行任务的线程数,唯一的非构造参数。 |
corePoolSize | 核心线程数量 , 当poolSize<corePoolSize,新增加一个线程处理新的任务。 |
maximumPoolSize | 最大线程数量,当poolSize=corePoolSize后有新的任务来的时候则会把任务加入到阻塞队列中等待,如果当队列满了以后判断poolSize<maximumPoolSize 则创建新的线程执行任务。 |
keepAliveTime | 线程池维护线程所允许的空闲时间。当线程池中的线程数量大于corePoolSize的时候,如果这时没有新的任务提交,核心线程外的线程不会立即销毁,而是会等待,直到等待的时间超过了,设置为0则不限时。 |
unit | 时间单位 |
workQueue | 等待队列,当任务提交时,如果线程池中的线程数量大于等于corePoolSize的时候,把该任务封装成一个Worker对象放入等待队列; |
threadFactory | 它是ThreadFactory类型的变量,用来创建新线程。 |
handler | 它是RejectedExecutionHandler类型的变量,表示线程池的饱和策略。如果阻塞队列满了并且没有空闲的线程,这时如果继续提交任务,就需要采取一种策略处理该任务,默认是使用拒绝策略。 如果队列满了并且poolSize=maximumPoolSize,那么线程池已经达到极限,会根据策略RejectedExecutionHandler拒绝新的任务。 |
2.四种线程池的使用
建议通过手动创建,使用Executors来创建线程池存在资源耗尽的可能,因为使用Executors来创建线程池队列默认的最大容量是Integer.Max
2.1.newSingleThreadExecutor
通俗描述: 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行,举例如做核酸检测,一个护士只能每次给一个人检测,其它的需要排队。
//通过Executors工具类创建
ExecutorService executor=Executors.newSingleThreadExecutor();
//Executors.newSingleThreadExecutor实现如下
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
2.2.newCachedThreadPool
通俗描述: 当有新任务到来,则插入到SynchronousQueue中,由于SynchronousQueue是同步队列,因此会在池中寻找可用线程来执行,若有可以线程则执行,若没有可用线程则创建一个线程来执行该任务;若池中线程空闲时间超过指定大小,则该线程会被销毁。
适用于执行很多短期异步的小程序或者负载较轻的服务器
//通过Executors工具类创建
ExecutorService cachedThreadPool =Executors.newCachedThreadPool();
//Executors.newCachedThreadPool实现如下
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
底层返回ThreadPoolExecutor实例,重要参数设置如下:
maximumPoolSize设置Integer.MAX_VALUE,keepAliveTime为60L,unit为TimeUnit.SECONDS(秒),workQueue设置为SynchronousQueue(同步队列)
2.3.NewScheduledThreadPool
用于替代jdk中的java.util.Timer定时类
通俗描述: 创建一个固定大小的线程池,线程池内线程存活时间无限制,线程池可以支持定时及周期性任务执行,如果所有线程均处于繁忙状态,对于新任务会进入DelayedWorkQueue队列中,这是一种按照超时时间排序的队列结构。
适用于周期性执行任务的场景底层
//通过Executors创建定时任务线程池
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
//Executors.newScheduledThreadPool具体实现
public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
new DelayedWorkQueue());
}
底层返回ScheduledThreadPoolExecutor实例,重要参数设置如下:
keepAliveTime为0L(不限时);unit为:TimeUnit.NANOSECONDS(纳秒);workQueue设置DelayedWorkQueue (一个按超时时间升序排序的队列)
过多长时间执行一次
类型于javascript中的setTimeout函数
Runnable r1 = () -> out.println("线程名称:" + Thread.currentThread().getName() + ",执行:3秒后执行");
scheduledThreadPool.schedule(r1, 3, TimeUnit.SECONDS);
间隔多少秒执行一次
类型于javascript中的setInterval函数
Runnable r2 = () -> out.println("线程名称:" + Thread.currentThread().getName() + ",执行:延迟2秒后每3秒执行一次");
scheduledThreadPool.scheduleAtFixedRate(r2, 2, 3, TimeUnit.SECONDS);
2.4.newFixedThreadPool
通俗描述: 创建可容纳固定数量线程的池子,每隔线程的存活时间是无限的,当池子满了就不在添加线程了;如果池中的所有线程均在繁忙状态,对于新任务会进入阻塞队列中(无界的阻塞队列)
//通过Executors工具类创建
ExecutorService fixedThreadPool=Executors.newFixedThreadPool(3);
//Executors.newFixedThreadPool实现如下
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
底层返回ThreadPoolExecutor实例,接收参数如下:
corePoolSize为nThread,maximumPoolSize为nThread;keepAliveTime为0L(不限时);unit设置为TimeUnit.MILLISECONDS;WorkQueue设置为 LinkedBlockingQueue(无界阻塞队列)。