线程池实现原理吐血总结

简介: 要理解实现原理,必须把线程池的几个参数彻底搞懂,不要死记硬背

要理解实现原理,必须把线程池的几个参数彻底搞懂,不要死记硬背


线程池参数

1、corePoolSize(必填):核心线程数。


2、maximumPoolSize(必填):最大线程数。


3、keepAliveTime(必填):线程空闲时长。如果超过该时长,非核心线程就会被回收。


4、unit(必填):指定keepAliveTime的时间单位。常用的有:TimeUnit.MILLISECONDS(毫秒)、TimeUnit.SECONDS(秒)、TimeUnit.MINUTES(分)。


5、workQueue(必填):任务队列。通过线程池的execute()方法提交的Runnable对象将存储在该队列中。


6、threadFactory(可选):线程工厂。一般就用默认的。


7、handler(可选):拒绝策略。当线程数达到最大线程数时就要执行饱和策略。


说下核心线程数和最大线程数的区别


拒绝策略可选值

1、AbortPolicy(默认):放弃任务并抛出RejectedExecutionException异常。

2、CallerRunsPolicy:由调用线程处理该任务。

3、DiscardPolicy:放弃任务,但是不抛出异常。可以配合这种模式进行自定义的处理方式。

4、DiscardOldestPolicy:放弃队列最早的未处理任务,然后重新尝试执行任务。


线程池执行流程

上个流程图,先试着自己看下能不能看懂

20210203170214141.png

简短的总结下线程池执行流程:


1、一个任务提交到线程池后,如果当前的线程数没达到核心线程数,则新建一个线程并且执行新任务,注意一点,这个新任务执行完后,该线程不会被销毁

2、如果达到了,则判断任务队列满了没,如果没满,则将任务放入任务队列;

3、如果满了,则判断当前线程数量是否达到最大线程数,如果没达到,则创建新线程来执行任务,注意,如果线程池中线程数量大于核心线程数,每当有线程超过了空闲时间,就会被销毁,直到线程数量不大于核心线程数;

4、如果达到了最大线程数,并且任务队列满了,就会执行饱和策略

四种现成的线程池

不想自己new线程池的话,可以用现成的


1、定长线程池(FixedThreadPool)


特点:只有核心线程,线程数量固定,执行完立即回收,任务队列为链表结构的有界队列。

应用场景:控制线程最大并发数


2、定时线程池(ScheduledThreadPool )


特点:核心线程数量固定,非核心线程数量无限,执行完闲置10ms后回收,任务队列为延时阻塞队列。

应用场景:执行定时或周期性的任务。


3、可缓存线程池(CachedThreadPool)


特点:无核心线程,非核心线程数量无限,执行完闲置60s后回收,任务队列为不存储元素的阻塞队列。

应用场景:执行大量、耗时少的任务。


4、单线程化线程池(SingleThreadExecutor)


特点:只有1个核心线程,无非核心线程,执行完立即回收,任务队列为链表结构的有界队列。

应用场景:不适合并发但可能引起IO阻塞性及影响UI线程响应的操作,如数据库操作、文件操作等。


上述四个线程池虽然方便,但是阿里巴巴规范明确说明不建议使用,因为可能会造成内存溢出,具体原因如下:


FixedThreadPool和SingleThreadExecutor:主要问题是堆积的请求处理队列均采用LinkedBlockingQueue,可能会耗费非常大的内存,严重的直接导致内存溢出。

CachedThreadPool和ScheduledThreadPool:主要问题是它们的最大线程数是Integer.MAX_VALUE,可能会创建数量非常多的线程,严重的直接导致内存溢出。


ok我话说完



相关文章
|
8月前
|
Java
【多线程系列】你先说说synchronized的实现原理
面试官:听说你精通多线程,那我就考考你吧面试官:不用慌尽管说,错了也没关系😊。。。❤️。
【多线程系列】你先说说synchronized的实现原理
|
存储 缓存 Java
一文读懂线程池的实现原理
一文读懂线程池的实现原理
281 0
一文读懂线程池的实现原理
|
1月前
|
监控 Java 开发者
深入理解Java中的线程池实现原理及其性能优化####
本文旨在揭示Java中线程池的核心工作机制,通过剖析其背后的设计思想与实现细节,为读者提供一份详尽的线程池性能优化指南。不同于传统的技术教程,本文将采用一种互动式探索的方式,带领大家从理论到实践,逐步揭开线程池高效管理线程资源的奥秘。无论你是Java并发编程的初学者,还是寻求性能调优技巧的资深开发者,都能在本文中找到有价值的内容。 ####
|
4月前
|
存储 缓存 Java
java线程内存模型底层实现原理
java线程内存模型底层实现原理
java线程内存模型底层实现原理
|
3月前
|
运维 API 计算机视觉
深度解密协程锁、信号量以及线程锁的实现原理
深度解密协程锁、信号量以及线程锁的实现原理
57 2
|
3月前
|
存储 运维 API
源码解密协程队列和线程队列的实现原理(一)
源码解密协程队列和线程队列的实现原理(一)
54 1
|
3月前
|
存储 安全 API
源码解密协程队列和线程队列的实现原理(二)
源码解密协程队列和线程队列的实现原理(二)
42 1
|
5月前
|
Java
【多线程面试题十六】、谈谈ReentrantLock的实现原理
这篇文章解释了`ReentrantLock`的实现原理,它基于Java中的`AbstractQueuedSynchronizer`(AQS)构建,通过重写AQS的`tryAcquire`和`tryRelease`方法来实现锁的获取与释放,并详细描述了AQS内部的同步队列和条件队列以及独占模式的工作原理。
【多线程面试题十六】、谈谈ReentrantLock的实现原理
|
5月前
|
安全 Java UED
Java线程池的实现原理及其在业务中的最佳实践
本文讲述了Java线程池的实现原理和源码分析以及线程池在业务中的最佳实践。
|
5月前
|
Java 调度
【多线程面试题十四】、说一说synchronized的底层实现原理
这篇文章解释了Java中的`synchronized`关键字的底层实现原理,包括它在代码块和方法同步中的实现方式,以及通过`monitorenter`和`monitorexit`指令以及`ACC_SYNCHRONIZED`访问标志来控制线程同步和锁的获取与释放。