Java线程池及配置参数详解
一、线程池的优点
合理利用线程池能够带来三个好处。
第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
第二:提高响应速度。当任务到达时,任务可以不需要的等到线程创建就能立即执行。
第三:提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。
二、线程池的创建
//参数初始化
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
//核心线程数量大小
private static final int corePoolSize = Math.max(2, Math.min(CPU_COUNT - 1, 4));
//线程池最大容纳线程数
private static final int maximumPoolSize = CPU_COUNT * 2 + 1;
//线程空闲后的存活时长
private static final int keepAliveTime = 30;//任务过多后,存储任务的一个阻塞队列
BlockingQueue<Runnable> workQueue = new SynchronousQueue<>();//线程的创建工厂
ThreadFactory threadFactory = new ThreadFactory() {private final AtomicInteger mCount = new AtomicInteger(1);public Thread newThread(Runnable r) {return new Thread(r, "AdvacnedAsyncTask #" + mCount.getAndIncrement());}
};//线程池任务满载后采取的任务拒绝策略
RejectedExecutionHandler rejectHandler = new ThreadPoolExecutor.DiscardOldestPolicy();//线程池对象,创建线程
ThreadPoolExecutor mExecute = new ThreadPoolExecutor(corePoolSize, //线程池的核心线程数maximumPoolSize,//线程池所能容纳的最大线程数keepAliveTime,//线程的空闲时间TimeUnit.SECONDS,//keepAliveTime对应的单位workQueue,//线程池中的任务队列threadFactory, //线程工厂rejectHandler//当任务无法被执行时的拒绝策略
);
创建一个线程池需要输入几个参数:
- corePoolSize(线程池的基本大小):当提交一个任务到线程池时,线程池会创建一个线程来执行任务,即使其他空闲的基本线程能够执行新任务也会创建线程,等到需要执行的任务数大于线程池基本大小时就不再创建。如果调用了线程池的prestartAllCoreThreads方法,线程池会提前创建并启动所有基本线程。
- runnableTaskQueue(任务队列):用于保存等待执行的任务的阻塞队列。可以选择以下几个阻塞队列。
- ArrayBlockingQueue:是一个基于数组结构的有界阻塞队列,此队列按 FIFO(先进先出)原则对元素进行排序。
- LinkedBlockingQueue:一个基于链表结构的阻塞队列,此队列按FIFO (先进先出) 排序元素,吞吐量通常要高于ArrayBlockingQueue。静态工厂方法Executors.newFixedThreadPool()使用了这个队列。
- SynchronousQueue:一个不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量通常要高于LinkedBlockingQueue,静态工厂方法Executors.newCachedThreadPool使用了这个队列。
- PriorityBlockingQueue:一个具有优先级得无限阻塞队列。
- maximumPoolSize(线程池最大大小):线程池允许创建的最大线程数。如果队列满了,并且已创建的线程数小于最大线程数,则线程池会再创建新的线程执行任务。值得注意的是如果使用了无界的任务队列这个参数就没什么效果。
- ThreadFactory:用于设置创建线程的工厂,可以通过线程工厂给每个创建出来的线程设置更有意义的名字,Debug和定位问题时非常又帮助。
- RejectedExecutionHandler(饱和策略):当队列和线程池都满了,说明线程池处于饱和状态,那么必须采取一种策略处理提交的新任务。这个策略默认情况下是AbortPolicy,表示无法处理新任务时抛出异常。以下是JDK1.5提供的四种策略。
1、ThreadPoolExecutor.AbortPolicy:
当线程池中的数量等于最大线程数时抛 java.util.concurrent.RejectedExecutionException 异常,涉及到该异常的任务也不会被执行,线程池默认的拒绝策略就是该策略。
2、ThreadPoolExecutor.DiscardPolicy():
当线程池中的数量等于最大线程数时,默默丢弃不能执行的新加任务,不报任何异常。
3、ThreadPoolExecutor.CallerRunsPolicy():
当线程池中的数量等于最大线程数时,重试添加当前的任务;它会自动重复调用execute()方法。
4、ThreadPoolExecutor.DiscardOldestPolicy():
当线程池中的数量等于最大线程数时,抛弃线程池中工作队列头部的任务(即等待时间最久的任务),并执行当前任务。
- keepAliveTime(线程活动保持时间):线程池的工作线程空闲后,保持存活的时间。所以如果任务很多,并且每个任务执行的时间比较短,可以调大这个时间,提高线程的利用率。
- TimeUnit(线程活动保持时间的单位):可选的单位有天(DAYS),小时(HOURS),分钟(MINUTES),毫秒(MILLISECONDS),微秒(MICROSECONDS, 千分之一毫秒)和毫微秒(NANOSECONDS, 千分之一微秒)。
三、线程池的工作原则
- 当线程池中线程数量小于 corePoolSize 则创建线程,并处理请求。
- 当线程池中线程数量大于等于 corePoolSize 时,则把请求放入 workQueue 中,随着线程池中的核心线程们不断执行任务,只要线程池中有空闲的核心线程,线程池就从 workQueue 中取任务并处理。
- 当 taskQueue 已存满,放不下新任务时则新建非核心线程入池,并处理请求直到线程数目达到 maximumPoolSize(最大线程数量设置值)。
- 如果线程池中线程数大于 maximumPoolSize 则使用 RejectedExecutionHandler 来进行任务拒绝处理。
Java线程池及配置参数详解相关推荐
- Java线程池七个参数详解
java多线程开发时,常常用到线程池技术,这篇文章是对创建java线程池时的七个参数的详细解释. 从源码中可以看出,线程池的构造函数有7个参数,分别是corePoolSize.maximumPoolS ...
- Java线程池七个参数详解:核心线程数、最大线程数、空闲线程存活时间、时间单位、工作队列、线程工厂、拒绝策略
源码简介 ThreadPoolExecutor是JDK中的线程池实现,这个类实现了一个线程池需要的各个方法,它提供了任务提交.线程管理.监控等方法. 下面是ThreadPoolExecutor类的构造 ...
- java线程池使用最全详解
线程池使用 前言 在执行一个异步任务或并发任务时,往往是通过直接new Thread()方法来创建新的线程,这样做弊端较多,更好的解决方案是合理地利用线程池,线程池的优势很明显,如下: 降低系统资源消 ...
- Java 线程池原理和队列详解
转载请标明出处:http://blog.csdn.net/xx326664162/article/details/51701508 文章出自:薛瑄的博客 你也可以查看我的其他同类文章,也会让你有一定的 ...
- Java线程池原理与实例详解
Wiki 采用new Thread的方式产生多线程,可能有以下一些问题: 线程的创建和销毁开销很大,尤其是有些线程的存在时间较短: 线程的创建和销毁过程中伴随着CPU在线程间的切换,开销很大: ...
- ThreadPoolExecutor线程池使用及参数详解
先贴一段实际应用代码,应用场景是一个基于http请求拦截的用户行为分析数据录入片段: package com.howbuy.coop.interceptor;import java.sql.Times ...
- Java线程池(ThreadPool)详解
线程五个状态(生命周期): 线程运行时间 假设一个服务器完成一项任务所需时间为:T1 创建线程时间,T2 在线程中执行任务的时间,T3 销毁线程时间. 如果:T1 + T3 远大于 T2,则可以采用线 ...
- future java 原理_Java线程池FutureTask实现原理详解
前言 线程池可以并发执行多个任务,有些时候,我们可能想要跟踪任务的执行结果,甚至在一定时间内,如果任务没有执行完成,我们可能还想要取消任务的执行,为了支持这一特性,ThreadPoolExecutor ...
- 线程池的执行原则及配置参数详解
池是一种非常优秀的设计思想,通过建立池可以有效的利用系统资源,节约系统性能.Java 中的线程池就是一种非常好的实现,从 JDK 1.5 开始 Java 提供了一个线程工厂 Executors 用来生 ...
最新文章
- 学术 | 一种新的CNN网络可以更高效地区分自然图像生成图像
- Python在ubuntu中更改Python和pip指向
- mysql的主从项目经验_mysql5.5主从经验分享
- Nacos简介、下载与配置持久化到Mysql
- 【论文解读】VarifocalNet:如何对候选框排序的最优方案
- 【thymeleaf】转义符:使用转义符拼接输出单引号
- 祖龙娱乐王远明:如何用UE4做出3A级材质和天气系统?
- 大数据每周分享第 008 期
- 报名开始!第二届中国移动“梧桐杯”大数据应用创新大赛邀你夺52w大奖!
- 看看30万码农怎么评论:培训出来的程序员真的很渣吗?
- DHCP报文类型和中继
- 复旦版最佳医院排行 沪21家医院入选全国百佳
- mercury已断开服务器无响应,Mercury水星无线路由器无法上网解决办法 | 192路由网...
- 分享 | 自定义属于自己的U盘图标
- ChatGPT ,能替代程序员吗?
- 【XSY2689】王子 - 网络流
- CHP城市猎人系统开发
- Android软件开发面试题,Android入门
- 布朗特克(Bron.tok)病毒专杀工具
- 图像处理-线性滤波-1 基础(相关算子、卷积算子、边缘效应)