最全线程池学习笔记

课件

📎异步&线程池.pdf

常见的 4 种线程池

底层都是new ThreadPoolExecutor()去创建,因此真实应用场景,自己去创建ThreadPoolExecutor并设置相关参数

newCachedThreadPool

public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}

创建一个可缓存线程池,所有线程执行完任务到达空闲时间均可被挥手,如果线程数超过线程处理需要,可灵活回收线程,无可回收,则创建新线程

newFixedThreadPool

public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}

创建一个定长线程,核心线程数和最大线程数均为设置的值,可控制最大并发数,超出的线程进入阻塞队列等待。

newScheduledThreadPool

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}

public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
new DelayedWorkQueue());
}

创建一个定长的线程池,其用的阻塞队列为延迟等待队列,会定时周期的执行任务

newSingleThreadExecutor

public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}

创建一个单线程化的线程池,他用唯一一个工作线程来执行任务,保证所有任务按照指定顺序(FIFO,LIFO,优先级)执行(只有一个在执行的线程,其他线程在阻塞队列中等待执行,处于阻塞队列中的线程可以按照上述制定规则等待被执行)

底层线程池的七大参数

* @param corePoolSize the number of threads to keep in the pool, even
* if they are idle, unless {
@code allowCoreThreadTimeOut} is set
*
@param maximumPoolSize the maximum number of threads to allow in the
* pool
*
@param keepAliveTime when the number of threads is greater than
* the core, this is the maximum time that excess idle threads
* will wait for new tasks before terminating.
*
@param unit the time unit for the {@code keepAliveTime} argument
*
@param workQueue the queue to use for holding tasks before they are
* executed. This queue will hold only the {
@code Runnable}
* tasks submitted by the {
@code execute} method.
*
@param threadFactory the factory to use when the executor
* creates a new thread
*
@param handler the handler to use when execution is blocked
* because the thread bounds and queue capacities are reached

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler)

1、corePoolSize:池中一直存在的线程数量,即使线程空闲,也存在,除非设置了allowCoreThreadTimeOut

2、maximumPoolSize:池中允许的最大线程数

3、keepAliveTime:当线程数大于核心线程数的时候,超出核心线程数的线程在最大多长时间没有接到新任务就会终止释放,可以释放的线程总数m-c,最终池子维持在corePoolSize 大小。

4、unit:时间单位

5、workQueue:阻塞队列,用来存储等待执行的任务,如果当前对线程的需求超过最大线程数,就在这里等待空闲线程执行。

三种阻塞队列

ArrayBlockingQueue 基于数组的先进先出队列,有界

LinkedBlockingQueue 基于链表的先进先出队列,无界

SynchronousQueue 无缓冲的等待队列,无界

6、threadFactory:创建线程的工厂,将Runnable接口 转为其实现Thread,开启线程。

public interface ThreadFactory {
Thread newThread(Runnable r);
}

7、handler:拒绝策略,如果线程池满了,队列也满了,还有并发请求线程池会使用特定拒绝策略进行拒绝,

四种拒绝策略

  • CallerRunsPolicy - 当触发拒绝策略,只要线程池没有关闭的话,则使用调用线程直接运行任务。一般并发比较小,性能要求不高,不允许失败。但是,由于调用者自己运行任务,如果任务提交速度过快,可能导致程序阻塞,性能效率上必然的损失较大
  • AbortPolicy - 丢弃任务,并抛出拒绝执行 RejectedExecutionException 异常信息。线程池默认的拒绝策略。必须处理好抛出的异常,否则会打断当前的执行流程,影响后续的任务执行。
  • DiscardPolicy - 直接丢弃,其他啥都没有
  • DiscardOldestPolicy - 当触发拒绝策略,只要线程池没有关闭的话,丢弃阻塞队列 workQueue 中最老的一个任务,并将新任务加入

线程池运行流程

1、线程池创建好,准备好核心数量的核心线程,准备接收任务

2、新的任务进来,用核心线程中的空闲线程执行

(1)、核心线程满了,就将再进来的线程放入阻塞队列,当核心线程执行完上一个任务,就去阻塞队列中获取任务执行

(2)、阻塞队列满了,就直接开新线程执行,最大能开到max指定的数量

(3)、max都执行好了,max-core数量空闲的线程会在keepAliveTime 自动销毁,最终保存core大小的线程

(4)、如果线程开到max的数量,还有新任务进来,就会使用rejecte指定拒绝策略进行处理

3、所有的线程创建都是由指定的factory创建的。

场景面试

一个线程池 core 7; ; max 20 ,queue :50 ,100 并发进来怎么分配的;

回答:先有7个能直接得到执行,接下来50个进入队列排队,队列满,再开13个线程继续执行。剩下的30个使用拒绝策略。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值