概述
Java线程池是运用最多的并发框架,学号多线程以及合理的使用多线程可以带来很大的好处,今天就来一起学习线程池相关的知识吧!
线程池
- 一、线程池的实现原理
- 二、使用线程池
- 1. 使用线程池的好处
- 2.线程池的创建
- 3. 向线程池提交任务
- 4. 关闭线程池
一、线程池的实现原理
当向线程池提交一个任务后,线程池会怎么做呢?
- 首先线程池会在核心线程
corePoolSize
中找是否都在执行任务,如果不是,就创建一个新的线程来分执行这个任务 - 如果核心线程都在执行任务,此时线程池判断工作队列
BlockingQueue
是否已满,如果没满,就把这个任务加到工作队列中 - 如果工作队列也满了,线程池就判断所有线程池中的线程
maximumPoolQueue
是否都在工作,如果不是,就创建一个新的工作线程来执行任务 - 如果都满了,那就会交给饱和策略去处理这个任务
可以结合流程图更好理解:
接下来展示一张在线程池中的执行流程图:
(图源自《Java并发编程的艺术》)
线程池在线程中执行任务分为两种情况:
- 在
execute()
方法中创建一个线程,让这个线程执行任务 - 这个线程执行完任务后,回反复的从
BlockingQueue
获取任务来执行
二、使用线程池
1. 使用线程池的好处
在开发中,合理的使用线程池可以带来很大的好处:
- 降低资源消耗,通过重复的利用以及创建的响线程降低线程创建和销毁的消耗
- 提高响应速度,当任务到达时,任务不需要等待线程创建就可以执行
- 提高线程的可管理性,如果无线的创建线程,不仅会消耗系统的资源,还会降低系统的稳定性,使用线程池可以进行统一的分配和监控。
2.线程池的创建
我们可以通过ThreadPoolExecutor来创建一个线程池
这是它拥有的构造方法们,我们来看看这些参数分别是什么:
- corePoolSize —— 线程池的基本大小:当提交一个任务到线程池是,线程池会创建一个线程来执行任务,即使其它空闲的基本线程能够执行新任务也会创建线程,等到任务数大于线程池基本大小时就不再创建。
- maximumPoolSize —— 线程池中允许的最大线程数 ,如果任务队列满了并且已经创建的线程小于最大线程数,则线程池会再创建新的线程执行任务。
- keepAliveTime —— 当线程数大于核心时,这是多余的空闲线程在终止之前等待新任务的最大时间。 超过这个时间线程就会被终止
- unit —— keepAliveTime参数的时间单位 ,可选单位有:天、小时、分钟、毫秒、微秒、纳秒
- workQueue —— 在执行任务之前用于保存任务的队列。 这个队列只会保存execute方法提交的Runnable任务。
可以选择以下几个阻塞队列:
(1) ArrayBlockingQueue: 一个基于数组结构的有界阻塞队列,按先进先出对元素排序
(2) LinkedBlockingQueue:一个基于链表结构的阻塞队列,按先进先出排序元素,吞吐量高于ArrayBlockingQueue
(3)PriorityBlockingQueue:一个具有优先级的无限阻塞队列 - handler —— 执行被阻止时使用的处理程序,因为达到线程限制和队列容量
有以下四种饱和策略(拒绝策略):
(1)AbortPolicy:直接抛出异常
(2)CallerRunsPolicy:只用调用者所在的这个线程来运行任务
(3)DiscardPolicy:不处理,丢弃掉,。如果线程队列已满,则后续提交的任务都会被丢弃,且是静默丢弃。
(4)DiscardOldestPolicy:丢弃掉队列中最老的一个任务,执行当前任务
默认拒绝策略为AbortPolicy
3. 向线程池提交任务
有两种方式向线程池提交任务分别是execute()
和submit()
方法
execute()
方法用于提交不用返回值的任务,所以无法判断任务是否被线程池执行成功。它的参数是一个Runnable
的实例。
submit()
方法用于提交需要返回值的任务。线程会返回一个future类型的对象,通过这个对象可以判断任务是否执行成功。
4. 关闭线程池
可以通过调用线程池的shutdown()
或者shutdownNow()
来关闭线程池,它的原理是遍历线程池中所有的线程,然后逐个调用线程的interrupt()方法中断线程,所以无法响应中断的任务有可能永远无法终止。
二者的区别是:
shutdownNow()
首先iang线程池的状态设为STOP
,然后尝试停止所有正在执行或暂停的线程,并返回等待执行任务的列表。
shutdown()
知识将线程池的状态设置为SHUTDOWN
,然后中断所有没有正在执行的任务。
通常调用shutdown()
方法关闭线程池,如果线程池中的任务不一定要执行完,可以调用shutdownNow()
方法。
唠唠叨叨:
这就是线程池的一些基本知识,更多的还是要在实践中慢慢体会,本文参考《Java并发编程的艺术》一书,有任何问题欢迎评论指正,也欢迎点赞关注一起进步。
最后
以上就是英俊小白菜为你收集整理的【Java 多线程】线程池 —— 详解线程池原理和使用一、线程池的实现原理二、使用线程池的全部内容,希望文章能够帮你解决【Java 多线程】线程池 —— 详解线程池原理和使用一、线程池的实现原理二、使用线程池所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复