哈喽,大家好,我是老王,欢迎来到第 7 期的 Java 面试突击。

本文的面试题是,当线程池的任务溢出之后,程序会奔溃吗?

这个问题问的是关于线程池的任务数超过线程池的承载能力之后,会出现什么情况?

那么,我们本文就手撸模拟一个线程池溢出的情况,来看程序的执行情况。

涉及知识点

  1. 核心线程数和最大线程数有什么区别?

  2. 如何模拟线程池溢出?

  3. 拒绝策略的执行流程是什么?

  4. 什么是线程池的拒绝策略?

  5. Java 自带的拒绝策略有哪些?

  6. 如何自定义拒绝策略?

视频面试答案

视频内容(因为视频比较大,分成了两个视频来展示 ):

图文面试答案

当线程池的任务溢出之后,程序并不会奔溃,这时候会触发线程池的拒绝策略,Java 自带的拒绝策略有四种:

  1. AbortPolicy:终止策略,线程池终止执行,并直接抛出异常,Java 默认此拒绝策略;

  2. CallerRunsPolicy:把任务交给当前线程执行(本来是线程池自己要执行的,结果处理不过来就交给当前的主线程去处理);

  3. DiscardPolicy:忽略此任务(最新的任务);

  4. DiscardOldestPolicy:忽略最早的任务(最久的任务)。

拒绝策略的执行流程比较绕,这是因为线程池有三个重要的参数:核心线程数(corePoolSize)、最大线程数(maximumPoolSize)、线程池的任务队列(BlockingQueue),大部分搞不清楚核心线程数和最大线程数有什么区别?

核心线程数是指在正常情况下线程池内的线程数量;而最大线程数指的是当线程池的任务队列存储超过最大值之后,可以创建最多的线程数量

当任务比较少的时候,线程数量会根据设置的超时时间,回归线程的数量为核心线程数量,这个时候最大线程数就暂时没用了(没有发挥的余地了)。

拒绝策略的执行流程是:当提交的任务数量大于核心线程数时,任务会被放入到线程池的任务队列中,当任务超过了最大队列值时,判断当前线程数量是否大于最大线程数,如果小于最大线程数则会新创建线程处理次任务,相反的情况下就会执行拒绝策略,如下图所示:

模拟线程池溢出

 public static void main(String[] args) {ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 4, 10, TimeUnit.SECONDS,new LinkedBlockingQueue<>(1),new ThreadPoolExecutor.AbortPolicy());for (int i = 0; i < 6; i++) {executor.execute(() -> {System.out.println(Thread.currentThread().getName());});}}

程序的执行结果如下:

pool-1-thread-2

pool-1-thread-2

pool-1-thread-1

pool-1-thread-3

pool-1-thread-4

Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task org.example.App$$Lambda$1/1096979270@7cca494b rejected from java.util.concurrent.ThreadPoolExecutor@7ba4f24f[Running, pool size = 4, active threads = 4, queued tasks = 1, completed tasks = 0]

at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2063)

at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:830)

at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1379)

at org.example.App.main(App.java:13)

从执行结果可以看出,循环在执行第 6 次就抛出异常了,这是因为最大线程数为 4,而队列最大只能存储 1 个任务,所以在第 6 个任务过来的时候,线程池已经超负荷运行了,只能执行拒绝策略了,而我们设置的拒绝策略是 AbortPolicy 所以会抛出异常。

自定义拒绝策略

除了 Java 自带的四种拒绝策略外,我们还可以自定义拒绝策略,代码如下:

public static void main(String[] args) throws InterruptedException {ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 4, 10, TimeUnit.SECONDS,new LinkedBlockingQueue<>(1), new RejectedExecutionHandler() {@Overridepublic void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {// 添加业务处理代码System.out.println("自定义拒绝策略");}});for (int i = 0; i < 7; i++) {executor.execute(() -> {System.out.println(Thread.currentThread().getName());});}
}

以上程序执行结果如下:

自定义拒绝策略

自定义拒绝策略

pool-1-thread-1

pool-1-thread-1

pool-1-thread-2

pool-1-thread-3

pool-1-thread-4

可以看出自定义拒绝策略,只需要重写 RejectedExecutionHandler 接口的 rejectedExecution 方法即可,可以在此方法中添加自己的业务处理代码。

小结

本文讲了线程池任务新增时的执行流程,先判断是否有空闲线程,如果的话直接执行任务,如果没有的话再判断任务队列是否是否饱和,如果不饱和把任务存储到队列中,如果饱和需要判断当前线程数是否大于最大线程数,如果小于则新增线程执行此任务,反之则执行拒绝策略。Java 提供了四种拒绝策略,你可以通过重写 RejectedExecutionHandler 接口来自定义拒绝策略。

更多执行细节和更多知识点说明,详见本文的视频部分。

【END】

近期热文

  • HashMap 为什么会导致 CPU 100%?面试突击 006 期

  • 面试突击 005 | Redis 是如何实现高可用的?它的实现方式有哪些?

  • 面试突击 004 | 如何排查 Redis 中的慢查询?视频实战篇

  • 面试突击 003 | Redis 如何实现查询附近的人?

  • 面试突击 002 | Redis 是如何处理已过期元素的?

  • 面试突击 001 | Redis 如何从海量数据中查询出某一个 Key?

  • Java面试详解(2020版):500+ 面试题和核心知识点详解

关注下方二维码,订阅更多精彩内容

朕已阅 

「视频版」当线程池溢出之后,程序会奔溃吗?面试突击 007 期相关推荐

  1. Redis都不懂?就别去面试了!聊聊我的Redis新专栏「视频版」

    前不久,有一个读者在后台留言,说他面试 Java 开发工程师岗位时,居然大部分的面试问题都是关于 Redis ,他都差点都忘记了自己应聘的是 Java 工程师了.而然这种现象在现在的后端面试中很常见, ...

  2. 面试突击 005 | Redis 是如何实现高可用的?它的实现方式有哪些?「视频版」

    这是我的第 35 篇原创文章 作者 | 老王(javacn666) 这部视频的录制.剪辑.做 PPT.写文稿大约花费了 5 个小时的时间,希望这种形式能被更多的人喜欢,希望这篇文章会给你带来更多的价值 ...

  3. Redis 中的过期元素是如何被处理的?「视频版」——面试突击 002 期

    本文以面试问题「Redis 中的过期元素是如何被处理的?」为切入点,用视频加图文的方式和大家聊聊 Redis 过期元素被处理的相关知识点. 涉及的知识点 过期删除策略有哪些? 这些过期策略有哪些优缺点 ...

  4. 使用 Redis 如何实现查询附近的人?「视频版」——面试突击 003 期

    面试问题 Redis 如何实现查询附近的人? 涉及知识点 Redis 中如何操作位置信息? GEO 底层是如何实现的? 如何在程序实现查询附近的人? 在实际使用中需要注意哪些问题? 视频答案 视频地址 ...

  5. 本周AI热点回顾:「时空版」Transformer训练速度远超3D CNN;拒绝内卷的AI狼火了!不想抓羊只想躺!...

    ‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍点击左上方蓝字关注我们 01 「时空版」Transformer训练速度远超3D CNN,提速3倍! Facebook AI推出了全新的视频理解架构TimeSform ...

  6. [免费专栏] Android安全之Android so文件分析「详细版」

    也许每个人出生的时候都以为这世界都是为他一个人而存在的,当他发现自己错的时候,他便开始长大 少走了弯路,也就错过了风景,无论如何,感谢经历 Android安全付费专栏长期更新,本篇最新内容请前往: [ ...

  7. 27亿参数的「野生版」GPT-3开源,GitHub项目2.9K Star量

    点击上方"AI遇见机器学习",选择"星标"公众号 重磅干货,第一时间送达 OpenAI 著名的语言模型 GPT-3 可以懂数学.翻译文字,还能写论文拿到及格成绩 ...

  8. 普通话测试第四题评分标准_2017年普通话水平测试评分细则「详细版」

    2017年普通话水平测试评分细则「详细版」 普通话是现代汉语的标准语.由国家语言文字工作委员会和国家教育委员会.广播电影电视部颁布的,<普通话水平测试等级标准(试行)>.以下是小编整理的2 ...

  9. 青岛计算机考试试题,2016年计算机一级上机考试题「word版」

    2016年计算机一级上机考试题「word版」 第1题. ****** 本套题共有2小题 ****** 一.在考生文件夹下打开文档WDT81.DOC.操作完成后以原文件名保存文档. (1)将文中所有错词 ...

最新文章

  1. 在ASP.NET中指定出错页面,不让代码外泄!
  2. python3教程-终于清楚python3详细教程
  3. CentOS-6.9升级到Python-3.5
  4. Spring Boot 揭秘与实战(二) 数据缓存篇 - EhCache
  5. html 文本框 自动拼接,HTML 中table的结构以及拼接
  6. python---文件处理
  7. 常见cmd命令,开发人员必备
  8. 垃圾回收算法与实现系列-线程安全与锁简介
  9. 非暴力拆解:小熊派NB-IoT通信扩展板
  10. C语言存储地址规律,一数组按顺序序存放,插入一个数,按原来排序规律放在相应位置...
  11. 第一章 在VS2008下如何配置好CG环境
  12. selinux详解及配置文件
  13. 教你webm格式怎么转换成mp4
  14. 剑指offer-刷题总结
  15. python os创建txt文件_Python新建动态命名txt文件
  16. 【力扣时间】【807】【中等】保持城市天际线
  17. 视频直播常见问题与解决办法汇总【系列一】
  18. 利用群发短信进行精准高效的会员营销
  19. Additive smoothing
  20. Tikz 画图技巧二

热门文章

  1. MySQL摘要_mysql摘要
  2. 在Ubuntu 8.04 LTS(hardy)下安装配置nginx和fastcgi方式的php
  3. 移动Web体验月报(6月):MIP 核心代码升级,增加基于 Vue 开发能力
  4. Qt的Xml操作QDomDocument
  5. 冒泡排序算法(C#)
  6. 最小生成树prim (c++ 已大改)
  7. jQuery的ajaxFileUpload上传文件插件刷新一次才能再次调用触发change
  8. 菜鸟学前端--javascript基础
  9. CSS 实现按钮及线呼吸灯效果
  10. Oracle 10g RAC 升级(CPU Update)之--升级CRS