接文章Java8线程池——底层为LinkedBlockingQueue的ThreadPoolExecutor,文章中简单介绍了线程池保持线程,并且从阻塞队列中获取任务执行的流程。本篇文章详细介绍线程池的几个重要的参数,以重要参数为线索更详细剖析线程池的实现细节。

参数corePoolSize——线程池的基本大小

线程池的目标大小,即在没有任务执行时线程池的大小,并且只有在工作队列满了的情况下才会创建超出这个数量的线程。

没有任务执行时线程池的大小,具体说是一个延时初始化,在线程池初始化的时候,并不会同时初始化线程,只有当任务到来时才会进行线程的创建,并且线程创建后会把这个任务作为其第一个任务执行。

只有在工作队列满了,这里的队列就是线程池中定义的阻塞队列,阻塞队列可以设置大小,默认的长度是整型的最大值Integer.MAX_VALUE。

参数maximumPoolSize——线程池的最大线程数

表示可以同时活动的线程数量的上线。如果某个线程的空闲时间超过了存活时间,那么将被标记为可回收的,并且当线程池的当前大小超过了基本大小时,这个线程将被终止。其实在实际之中还有一个参数的设置allowCoreThreadTimeOut,设置true,允许线程池中所有的线程超时,这时不再需要线程数量超过基本大小这个判断条件。

代码片段如下:

如何实现的超时时间判断?利用阻塞队列的等待超时机制实现,如果在设定的时间内取不到任务,返回null,会把变量timedOut设置为true,表示已经超时。

Runnable r = timed ?

workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :

workQueue.take();

在参数allowCoreThreadTimeOut和判断当前线程是否超过基本大小共同影响下,设置timed参数的值。

boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;

变量timedOut和timed同时为true时,根据判断会终止线程。否则线程继续for循环进行自旋,等待任务的到来。

if ((wc > maximumPoolSize || (timed && timedOut)) && (wc > 1 || workQueue.isEmpty())) {

if (compareAndDecrementWorkerCount(c)

return null;

continue;

}

getTask方法如下图:

参数keepAliveTime——超出基本大小的线程空闲状态的最长时间

如果变量allowCoreThreadTimeOut设置为true,所有线程都会可能超时,默认为false,只有超出基本大小的线程会超时。线程空闲的时间超过keepAliveTime,并且线程数量大于基本大小,线程会被终止。具体实现参看上面参数maximumPoolSize中讲解的代码。

RejectedExecutionHandler饱和策略

当有界队列被填满后,饱和策略发挥作用,可以通过调用setRejectedExecutionHandler设置。默认策略是抛出未检查的异常RejectedExecutionException,调用者可以捕获这个异常,根据需求处理,也可以快速定位到队列被填满。另外,还有策略直接抛弃到来的任务,或者抛弃下一个将被执行的任务,尝试提交新的任务。最后还可以实现将任务既不遗弃,也不抛出异常,而是把任务回退给调用者。在ThreadPoolExecutor中对应的类分别是:AbortPolicy,DiscardPolicy,DiscardOldestPolicy和CallerRunsPolicy。

java 线程池 初始大小,Java线程池ThreadPoolExecutor的实现和参数相关推荐

  1. java 线程池 初始大小_为什么tomcat的默认线程池大小如此之大? - java

    我注意到默认的tomcat 7线程池大小似乎是200. 但是普通的CPU似乎有16个内核. 因此只能并行执行16个线程 为什么tomcat使用那么多线程. 参考方案 多年以来,许多单核计算机问世,并且 ...

  2. java 队列占用内存大小_Java线程池队列吃的太饱,撑着了咋整?java 队列过大导致内存溢出...

    Java的Executors框架提供的定长线程池内部默认使用LinkedBlockingQueue作为任务的容器,这个队列是没有限定大小的,可以无限向里面submit任务. 当线程池处理的太慢的时候, ...

  3. [Java并发编程(二)] 线程池 FixedThreadPool、CachedThreadPool、ForkJoinPool?为后台任务选择合适的 Java executors...

    [Java并发编程(二)] 线程池 FixedThreadPool.CachedThreadPool.ForkJoinPool?为后台任务选择合适的 Java executors ... 摘要 Jav ...

  4. java workerdone_【架构】Java并发编程——线程池的使用

    前言 如果我们要使用线程的时候就去创建一个,这样虽然非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为 ...

  5. Java多线程系列(三):Java线程池的使用方式,及核心运行原理

    之前谈过多线程相关的4种常用Java线程锁的特点,性能比较.使用场景,今天主要分享线程池相关的内容,这些都是属于Java面试的必考点. 为什么需要线程池 java中为了提高并发度,可以使用多线程共同执 ...

  6. java 队列线程池_JAVA工作队列与线程池

    为什么要使用线程池? 诸如 Web 服务器.数据库服务器.文件服务器或邮件服务器之类的许多服务器应用程序都面向处理来自某些远程来源的大量短小的任务.请求以某种方式到达服务器,这种方式可能是通过网络协议 ...

  7. Java高频面试题(2022) - Java、Mysql、JUC、JVM、SSM

    目录 不好使!点右边小目录定位: 目录 JavaSE HashMap底层原理?★★ Vector.ArryList.LinkedList 的区别与联系 Hashtable与HashMap的区别?如何解 ...

  8. Linux系统编程----15(线程与进程函数之间的对比,线程属性及其函数,线程属性控制流程,线程使用注意事项,线程库)

    对比 进程 线程 fork pthread_create exit (10) pthread_exit (void *) wait (int *) pthread_join (,void **)阻塞 ...

  9. Java 确定线程池中工作线程数的大小

    以问答形式展开,会更有针对性: 1.工作线程是不是越多越好? 不是.a.服务器cpu核数有限,所以同时并发或者并行的线程数是有限的,所以1核cpu设置1000个线程是没有意义的. b.线程切换也是有开 ...

最新文章

  1. 如何系统的学习单片机?
  2. linux下更改MySQL数据库存储目录
  3. c++ 将输入存储到数组,然后反转数组,最后输出
  4. Java 洛谷 P1426 小鱼会有危险吗
  5. ios pan手势滑动消失动画_iOS仿抖音—评论视图滑动消失
  6. 中文信息处理(二)—— 分词
  7. OSI七层模型中的网络层与传输层
  8. 搭建vue开发环境的步骤
  9. 文件转换swf/flv
  10. jmeter ramp-up-period设置以及同步定时器使用
  11. Ant-design 源码分析之数据展示(八)Descriptions
  12. 传奇私服架设入门教程分享
  13. 十九. 用户注册 --- 短信验证码实现 2021-04-16
  14. matlab动图启动,MATLAB制作动图或视频
  15. Accept CS Ph.D. Offer from Stony Brook University,去SUNY石溪大学的CS Ph.D.啦
  16. 看了鲁迅的平面设计,很多设计师表示可能要转行了
  17. Vue3源码解析01--Vue3初探
  18. iOS之KVC原理自定义KVC
  19. windows调整jadx的使用内存大小
  20. 计算机考研时间科目,2018年考研初试各科目时间安排清单

热门文章

  1. 25~50K|云视科技SLAM算法工程师/机器人算法软件工程师招聘(社招+实习)
  2. LeetCode 845. 数组中的最长山脉
  3. Jupyter Notebook各种使用方法
  4. AAAI 2020 | MaskGEC:通过动态掩蔽改善语法纠错
  5. CentOS 7(64位)系统中安装AutoDockTools(MGLTools)
  6. 关于自注意力机制的思考
  7. 提取so文件的特征值
  8. NAR:查询未培养病毒基因组的综合生态和进化框架IMG/VR v3
  9. IF10+的数据库文章!生物信息数据库承建!
  10. MIMOSA2: 基于微生物组和代谢组数据的整合分析