目录
- 前言
- 正文
- 使用线程池的好处
- ThreadPoolExecutor构造参数详解
- 如何使用线程池
- execute()和submit()区别
- Executors提供的线程池配置方案
- 构造一个固定线程数目的线程池,配置的corePoolSize与maximumPoolSize大小相同,同时使用了一个无界LinkedBlockingQueue存放阻塞任务,因此多余的任务将存在再阻塞队列,不会由RejectedExecutionHandler处理
- 构造一个缓冲功能的线程池,配置corePoolSize=0,maximumPoolSize=Integer.MAX_VALUE,keepAliveTime=60s,以及一个无容量的阻塞队列 SynchronousQueue,因此任务提交之后,将会创建新的线程执行;线程空闲超过60s将会销毁
- 构造一个只支持一个线程的线程池,配置corePoolSize=maximumPoolSize=1,无界阻塞队列LinkedBlockingQueue;保证任务由一个线程串行执行
- 参考文章
前言
线程经常用,线程池也用,但在于如何使用,没有记录一下。
本文参考别人文章整理。
正文
使用线程池的好处
- 降低内存资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
- 提高响应速度。在线程池中的线程都是已经被创建好的,我们的任务直接获取一个空闲的线程就能够被执行了
- 提高线程的可管理性。使用线程池可以进行统一分配、调优和监控。线程是稀缺资源,如果无限制地创建,不仅会消耗系统资源,还会降低系统的稳定性。
ThreadPoolExecutor构造参数详解
比如
/**
* 参数信息:
* int corePoolSize 核心线程大小
* int maximumPoolSize 线程池最大容量大小
* long keepAliveTime 线程空闲时,线程存活的时间
* TimeUnit unit 时间单位
* BlockingQueue<Runnable> workQueue 任务队列。一个阻塞队列
* threadFactory :
* RejectedExecutionHandler :新建线程工厂 当提交任务数超过maxmumPoolSize+workQueue之和时,任务会交给RejectedExecutionHandler来处理
*/
mThreadPoolExecutor = new ThreadPoolExecutor(2, 4, 5, TimeUnit.SECONDS, new ArrayBlockingQueue<>(2), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
- corePoolSize : 核心线程池大小
- maximumPoolSize : 最大线程池大小
- keepAliveTime : 线程池中超过corePoolSize数目的空闲线程最大存活时间;可以allowCoreThreadTimeOut(true)使得核心线程有效时间
- TimeUnit : keepAliveTime时间单位
- workQueue : 阻塞任务队列
- threadFactory : 新建线程工厂
- RejectedExecutionHandler : 当提交任务数超过maxmumPoolSize+workQueue之和时,任务会交给RejectedExecutionHandler来处理
corePoolSize,maximumPoolSize,workQueue之间关系
- 当线程池小于corePoolSize时,新提交任务将创建一个新线程执行任务,即使此时线程池中存在空闲线程。
- 当线程池达到corePoolSize时,新提交任务将被放入workQueue中,等待线程池中任务调度执行
- 当workQueue已满,且maximumPoolSize>corePoolSize时,新提交任务会创建新线程执行任务
- 提交任务数超过maximumPoolSize时,新提交任务由RejectedExecutionHandler处理
- 线程池中超过corePoolSize线程,空闲时间达到keepAliveTime时,关闭空闲线程
- 当设置allowCoreThreadTimeOut(true)时,线程池中corePoolSize线程空闲时间达到keepAliveTime也将关闭
如何使用线程池
mThreadPoolExecutor.execute(Runnable);
mThreadPoolExecutor.submit(Runnable);
execute()和submit()区别
- execute()是ThreadPoolExecutor的方法
- submit()是ExecutorService的方法
- execute(..) 方法用于提交不需要返回值的任务,所以无法判断任务是否被线程池执行成功。
- submit(..) 方法用于提交需要返回值的任务。线程池会返回一个 future 类型的对象,通过这个 future 对象可以判断任务是否执行成功,并且可以通过 future 的 get() 方法来获取返回值,get() 方法会阻塞当前线程直到任务完成,而使用 get(long timeout,TimeUnit unit)方法则会阻塞当前线程一段时间后立即返回,这时候有可能任务没有执行完。
Executors提供的线程池配置方案
构造一个固定线程数目的线程池,配置的corePoolSize与maximumPoolSize大小相同,同时使用了一个无界LinkedBlockingQueue存放阻塞任务,因此多余的任务将存在再阻塞队列,不会由RejectedExecutionHandler处理
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
构造一个缓冲功能的线程池,配置corePoolSize=0,maximumPoolSize=Integer.MAX_VALUE,keepAliveTime=60s,以及一个无容量的阻塞队列 SynchronousQueue,因此任务提交之后,将会创建新的线程执行;线程空闲超过60s将会销毁
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
构造一个只支持一个线程的线程池,配置corePoolSize=maximumPoolSize=1,无界阻塞队列LinkedBlockingQueue;保证任务由一个线程串行执行
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
参考文章
- 《ThreadPoolExecutor使用详解》
- 《[ThreadPoolExecutor的使用])(https://blog.csdn.net/Day_and_Night_2017/article/details/124404629)》
- 《ThreadPoolExecutor的使用方法》
- 《Java多线程 ThreadPoolExecutor-RejectedExecutionHandler拒绝执行策略》
- 《线程池ThreadPoolExecutor的使用详解》
历史上的今天
暂无评论...
随机推荐
Android Studio使用makejar导出jar包
前言记录一下如何使用makejar导出jar包。正文这里lib库PhotoView来说。PhotoView/build.gradle 新增如下内容:task clearJar(type: Delete) { delete rootProject.file("PhotoView/j...
余华:麦田里
我在南方长大成人,一年四季、一日三餐的食物都是大米,由于很少吃包子和饺子,这类食物就经常和节日有点关系了。小时候,当我看到做外科医生的父亲手里提着一块猪肉,捧着一袋面粉走回家时,我就知道这一天是什么日子了。在我小时候有很多节日,五月一日是劳动节,六月一日是儿童节,七月一日是建党节,八月一日是建军节,...
在Ubuntu14上搭建wordpress网站
网址需要开启一定的端口号咯 比如重定位80端口到443端口(https需要)等等,这里是这里过去很久了,部分不再适合使用[2024备注]更新系sudo apt-get updatesudo apt-get upgrade开始安装lamp环境sudo apt-get inst...
吴念真:饱了别人,瘦了自己
当我们第一眼看到阿婆的自助餐厅时,还以为自己找错了地方呢!以为自己走入了一个工地的厨房,一个受雇的欧巴桑正准备免费的午餐,等待忙了一个早上的工人,让他们填饱肚子。话说回来,这样的印象跟事实其实相去不远。经营这家没有招牌的自助餐厅的阿婆庄朱玉女士,唯一的经营哲学就是让你吃到饱!今年七十六岁的她,从早...
铁凝:一千张糖纸
小学一年级的暑假里,我去北京外婆家做客。正是“七岁八岁讨人嫌”的年龄,外婆的四合院里到处都有我的笑闹声。加之隔壁院子一个名叫世香的女孩子跑来和我做朋友,我们两人的种种游戏更使外婆家不得安宁了。我们在院子里跳皮筋,把青砖地跺得砰砰响;我们在枣树下的方桌上玩“抓子儿”,“羊拐”撒在桌面上一阵又一阵哗啦...
使用starUML建立时序图的简单记录
前言starUML不是经常用,每次要用时就是忘记,因此今天有空就简单记录一下,方便自己查阅。好记性不如烂笔头正文StarUML(简称SU),是一种创建UML类图,生成类图和其他类型的统一建模语言(UML)图表的工具。StarUML是一个开源项目之一发展快、灵活、可扩展性强(zj).Star...