【从源码理解】Java线程池(简介篇)
Introduction
阅读有三个前提:
学过Java基础知识,知道Java线程的概念。
学过Java基础知识,知道Java线程的概念。
学过Java基础知识,知道Java线程的概念。
重要的事情说三遍,不要您的时间~
What
文章的开始,我们当然先要说清楚什么是线程池。
根据【java.util.concurrent.ThreadPoolExecutor】的源码注释,线程池是一种【统一】控制【Java线程】的,基于【java.util.concurrent.Executors】的【工厂模式】的服务。
线程池通常主要用于解决两类问题:
通过减少每个【预任务(pre-task)】的调用,对大批量【异步】任务进行性能优化。
通过管理线程任务的调度,静态变量的统计(如已完成任务数量),为绑定、管理资源赋予意义。
Why
相信上面的“What”已经让大家开始"What the f"了,我一向认为理解一个事物是什么的最好方法是理解为什么这个事物会存在。这里简单说一下我的理解:
1. 【代码层面】单独管理线程,会出现大量的线程启动与关闭,这样会导致代码难以把控,容易挖坑。
2. 【性能层面】线程的创建是会消耗机器资源的,有了线程池可以避免过度消耗,用线程池做缓存,统一分配任务进行调优与监控。
When
那么问题来了,什么时候我们需要使用线程池呢?
这个问题就很灵活了。根据工作经验我总结一下什么时候会用到线程池(按使用评率):
面试的时候(喂喂喂你怎么面向工资编程这不合理吧)
单个任务处理时间比较短,但处理的任务量很大的时候(比如您的下游接口不支持批量调用)
项目刚启动,需要快速交付,没有资源引入方便快捷简单易用的各种第三方分布式花花框架时
和同事/同学炫耀时
How
关于怎么使用线程池,这里就先简单粗略的用伪代码写个最简单的创建,并介绍一下各参数的意义,在之后的文章里再展开说说细节~
【印度口音】Dalg is cheab, show me the gode! (Talk is cheap, show me the code!)
使用构造函数创建:
final ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) ;
corePoolSize: 线程池内的核心线程数。
maximumPoolSize: 线程池允许的最大线程数。如果超过的最大线程数,根据线程池的种类不一样会有不同的处理方式,以后的文章会写~
keepAliveTime: 如果线程的数量超过了线程池的核心线程数,超出的线程等待最长时间
unit: keepAliveTime的时间单位(线程池有提供枚举,感兴趣的同学可以看看源码)
workQueue: 数量超过的线程会在queue里面进行等待(看线程池策略,不是都会有这个队列的)进队的只会是被execute提交的Runnable任务。
threadFactory: 用来创建新线程的excutor工厂
handler: 指定线程阻塞后的拒绝策略,也会在之后的文章中解释。
今天的文章就到这里了~
最后祝大家身体健康。迎财神!