一、线程池的优点

合理利用线程池能够带来三个好处。

第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。

第二:提高响应速度。当任务到达时,任务可以不需要的等到线程创建就能立即执行。

第三:提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。

二、线程池的创建

//参数初始化
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(任务队列):用于保存等待执行的任务的阻塞队列。可以选择以下几个阻塞队列。
  1. ArrayBlockingQueue:是一个基于数组结构的有界阻塞队列,此队列按 FIFO(先进先出)原则对元素进行排序。
  2. LinkedBlockingQueue:一个基于链表结构的阻塞队列,此队列按FIFO (先进先出) 排序元素,吞吐量通常要高于ArrayBlockingQueue。静态工厂方法Executors.newFixedThreadPool()使用了这个队列。
  3. SynchronousQueue:一个不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量通常要高于LinkedBlockingQueue,静态工厂方法Executors.newCachedThreadPool使用了这个队列。
  4. 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, 千分之一微秒)。

三、线程池的工作原则

  1. 当线程池中线程数量小于 corePoolSize 则创建线程,并处理请求。
  2. 当线程池中线程数量大于等于 corePoolSize 时,则把请求放入 workQueue 中,随着线程池中的核心线程们不断执行任务,只要线程池中有空闲的核心线程,线程池就从 workQueue 中取任务并处理。
  3. 当 taskQueue 已存满,放不下新任务时则新建非核心线程入池,并处理请求直到线程数目达到 maximumPoolSize(最大线程数量设置值)。
  4. 如果线程池中线程数大于 maximumPoolSize 则使用 RejectedExecutionHandler 来进行任务拒绝处理。

Java线程池及配置参数详解相关推荐

  1. Java线程池七个参数详解

    java多线程开发时,常常用到线程池技术,这篇文章是对创建java线程池时的七个参数的详细解释. 从源码中可以看出,线程池的构造函数有7个参数,分别是corePoolSize.maximumPoolS ...

  2. Java线程池七个参数详解:核心线程数、最大线程数、空闲线程存活时间、时间单位、工作队列、线程工厂、拒绝策略

    源码简介 ThreadPoolExecutor是JDK中的线程池实现,这个类实现了一个线程池需要的各个方法,它提供了任务提交.线程管理.监控等方法. 下面是ThreadPoolExecutor类的构造 ...

  3. java线程池使用最全详解

    线程池使用 前言 在执行一个异步任务或并发任务时,往往是通过直接new Thread()方法来创建新的线程,这样做弊端较多,更好的解决方案是合理地利用线程池,线程池的优势很明显,如下: 降低系统资源消 ...

  4. Java 线程池原理和队列详解

    转载请标明出处:http://blog.csdn.net/xx326664162/article/details/51701508 文章出自:薛瑄的博客 你也可以查看我的其他同类文章,也会让你有一定的 ...

  5. Java线程池原理与实例详解

    Wiki 采用new Thread的方式产生多线程,可能有以下一些问题:  线程的创建和销毁开销很大,尤其是有些线程的存在时间较短:  线程的创建和销毁过程中伴随着CPU在线程间的切换,开销很大: ...

  6. ThreadPoolExecutor线程池使用及参数详解

    先贴一段实际应用代码,应用场景是一个基于http请求拦截的用户行为分析数据录入片段: package com.howbuy.coop.interceptor;import java.sql.Times ...

  7. Java线程池(ThreadPool)详解

    线程五个状态(生命周期): 线程运行时间 假设一个服务器完成一项任务所需时间为:T1 创建线程时间,T2 在线程中执行任务的时间,T3 销毁线程时间. 如果:T1 + T3 远大于 T2,则可以采用线 ...

  8. future java 原理_Java线程池FutureTask实现原理详解

    前言 线程池可以并发执行多个任务,有些时候,我们可能想要跟踪任务的执行结果,甚至在一定时间内,如果任务没有执行完成,我们可能还想要取消任务的执行,为了支持这一特性,ThreadPoolExecutor ...

  9. 线程池的执行原则及配置参数详解

    池是一种非常优秀的设计思想,通过建立池可以有效的利用系统资源,节约系统性能.Java 中的线程池就是一种非常好的实现,从 JDK 1.5 开始 Java 提供了一个线程工厂 Executors 用来生 ...

最新文章

  1. 学术 | 一种新的CNN网络可以更高效地区分自然图像生成图像
  2. Python在ubuntu中更改Python和pip指向
  3. mysql的主从项目经验_mysql5.5主从经验分享
  4. Nacos简介、下载与配置持久化到Mysql
  5. 【论文解读】VarifocalNet:如何对候选框排序的最优方案
  6. 【thymeleaf】转义符:使用转义符拼接输出单引号
  7. 祖龙娱乐王远明:如何用UE4做出3A级材质和天气系统?
  8. 大数据每周分享第 008 期
  9. 报名开始!第二届中国移动“梧桐杯”大数据应用创新大赛邀你夺52w大奖!
  10. 看看30万码农怎么评论:培训出来的程序员真的很渣吗?
  11. DHCP报文类型和中继
  12. 复旦版最佳医院排行 沪21家医院入选全国百佳
  13. mercury已断开服务器无响应,Mercury水星无线路由器无法上网解决办法 | 192路由网...
  14. 分享 | 自定义属于自己的U盘图标
  15. ChatGPT ,能替代程序员吗?
  16. 【XSY2689】王子 - 网络流
  17. CHP城市猎人系统开发
  18. Android软件开发面试题,Android入门
  19. 布朗特克(Bron.tok)病毒专杀工具
  20. 图像处理-线性滤波-1 基础(相关算子、卷积算子、边缘效应)

热门文章

  1. 51nod 1113 矩阵快速幂【裸题】【内含黑科技】
  2. 对文件进行筛选c语言,用c语言实现文本文件中的字符筛选分析。
  3. 重磅!在 Mac 上接收 iphone 手机短信!
  4. 大数据采集(hdu)第二章笔记
  5. 求佩波拉切数列的前20项
  6. 自动摘要生成 tf-idf+doc2vec+句子聚类
  7. VUE plugin 插件
  8. 查分吧(chafenba)通用成绩查询系统免费下载
  9. (附源码)ssm+mysql+基于SSM框架的图片分享及评价网站设计与实现 毕业设计201524
  10. C语言实现高精度减法