Java~线程池与线程池的优化(1)

本文介绍了Java中不同类型的线程池(如定长线程池、定时线程池和可缓存线程池),分析了它们的特点以及可能遇到的问题,特别是关于最大线程数可能导致OOM的提示。还提到自定义线程池时需要理解的7个参数含义,并提供了资源管理和优化的建议。
摘要由CSDN通过智能技术生成

线程池


  • 程序的运行要创建进程, 进程中任务的执行要创建线程去执行, 而频繁的创建线程是很耗费资源的,为了优化资源就采用了池化技术, 比如线程池和数据库连接池

  • 池化技术就是事先准备好一些资源, 有人要拿就去用, 没人拿就放那

  • 降低了创建和销毁的效率, 提高了响应的速度, 方便了管理(可以控制最大并发数, 管理线程),实现了程序的复用

核心线程池


定长线程池(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

总结

  1. FixedThreadPool和SingleThreadPool中的LinkedBlockIngQueue的默认允许长度为Integer.MAX_VALUE, 可能会堆积大量的请求, 从而导致OOM

LinkedBlockingQueue: 一个由链表结构组成的有界阻塞队列,在未指明容量时,容量默认为Integer.MAX_VALUE。

  1. 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, //线程工厂, 创建线程需要使用, 一般不用修改
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

在面试前我整理归纳了一些面试学习资料,文中结合我的朋友同学面试美团滴滴这类大厂的资料及案例

MyBatis答案解析
由于篇幅限制,文档的详解资料太全面,细节内容太多,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!

大家看完有什么不懂的可以在下方留言讨论也可以关注。

觉得文章对你有帮助的话记得关注我点个赞支持一下!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
7)]
由于篇幅限制,文档的详解资料太全面,细节内容太多,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!

大家看完有什么不懂的可以在下方留言讨论也可以关注。

觉得文章对你有帮助的话记得关注我点个赞支持一下!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值