定长线程池(FixedThreadPool)
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue());
}
-
nThreads在初始化的时候就订好了, 并且他的核心线程和最大线程数目是相同的, 主要用在服务器上, 可以控制最大的并发数
-
但是他有缺点他的任务队列BlockIngQueue的允许长度了Integer.MAX_VALUE, 可能会堆积大量的请求, 从而导致OOM
定时线程池(ScheduledThreadPool )
public static ScheduledExecutorService newScheduledThreadPool(
int corePoolSize, ThreadFactory threadFactory) {
return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
-
核心线程也是固定的, 最大线程数量是无限的, 可以执行定时任务和周期任务
-
缺点就是因为其最大线程是Integer.MAX_VALUE 可能会创建大量的线程, 从而导致OOM
可缓存线程池(CachedThreadPool)
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue());
-
无核心线程, 并且其最大线程数目也是无限的, 默认是60s后回收, 任务队列为不存储任务的阻塞队列, 用于执行量大, 任务短小的场景
-
缺点就是因为其最大线程是Integer.MAX_VALUE 可能会创建大量的线程, 从而导致OOM
单线程化线程池(SingleThreadExecutor)
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue()));
-
核心线程和最大线程都是1, 用完即可回收线程, 任务队列为链表结构的有界队列, 用于不适合并发,但可能有阻塞的场景, 或者一些短小任务
-
缺点还是他的任务列表的最大值还是Integer.MAX_VALUE, 可能会堆积大量的请求, 从而导致OOM
总结
- FixedThreadPool和SingleThreadPool中的LinkedBlockIngQueue的默认允许长度为Integer.MAX_VALUE, 可能会堆积大量的请求, 从而导致OOM
LinkedBlockingQueue: 一个由链表结构组成的有界阻塞队列,在未指明容量时,容量默认为Integer.MAX_VALUE。
- CachedThreadPool和ScheduledThreadPool允许创建的线程的最大值是Integer.MAX_VALUE 可能会创建大量的线程, 从而导致OOM
SynchronousQueue(CachedThreadPool使用):一个不存储元素的阻塞队列,消费者线程调用take()方法的时候就会发生阻塞,直到有一个生产者线程生产了一个元素,消费者线程就可以拿到这个元素并返回;生产者线程调用put()方法的时候也会发生阻塞,直到有一个消费者线程消费了一个元素,生产者才会返回。
-
通过源码我们发现, 上述在构建线程的时候都是使用ThreadPoolExecutor构建, 那我们就对我们实际的需求来设计一个满足我们自身的线程池
-
但是我们发现如果自定义会有7个参数, 如果想要自定义线程池就必须知道这7个参数的意思
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
七个参数
public ThreadPoolExecutor(int corePoolSize, //核心线程数目
int maximumPoolSize, //最大线程数目
long keepAliveTime, //线程保活时间
TimeUnit unit, //保活时间单位
BlockingQueue workQueue, //存放任务的阻塞队列
ThreadFactory threadFactory, //线程工厂, 创建线程需要使用, 一般不用修改
RejectedExecutionHandler handler //拒绝策略) {
-
corePoolSize(必需):核心线程数。默认情况下,核心线程会一直存活,但是当将allowCoreThreadTimeout设置为true时,核心线程也会超时回收。
-
maximumPoolSize(必需):线程池所能容纳的最大线程数。当活跃线程数达到该数值后,后续的新任务将会阻塞。
-
keepAliveTime(必需):线程闲置超时时长。如果超过该时长,非核心线程就会被回收。如果将allowCoreThreadTimeout设置为true时,核心线程也会超时回收。
-
unit(必需):指定keepAliveTime参数的时间单位。常用的有:TimeUnit.MILLISECONDS(毫秒)、TimeUnit.SECONDS(秒)、TimeUnit.MINUTES(分)。
-
workQueue(必需):任务队列。通过线程池的execute()方法提交的Runnable对象将存储在该参数中。其采用阻塞队列实现。
-
threadFactory(可选):线程工厂。用于指定为线程池创建新线程的方式。(一般都是使用默认的)
-
handler(可选):拒绝策略。当达到最大线程数并且任务对队列也满了时需要执行的饱和策略。
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!**
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!