【Java 开发日记】阻塞队列有哪些?拒绝策略有哪些?

【Java 开发日记】阻塞队列有哪些?拒绝策略有哪些?

目录

阻塞队列有哪些?

拒绝策略有哪些?

面试回答


阻塞队列有哪些?

在Java的java.util.concurrent包里面,阻塞队列的实现挺多的,我们可以根据它的功能和结构来记,主要分这么几类:

1. 按容量划分:

  • 有界队列: 就是队列有固定的容量。
    • ArrayBlockingQueue 最经典的一个,底层是数组,创建时必须指定大小。它的生产和消费用同一把锁,性能相对稳定。
    • LinkedBlockingQueue 底层是链表,它既可以是有界的(构造时指定容量),也可以默认是无界的(默认是Integer.MAX_VALUE,几乎相当于无界)。它的生产和消费用了两把锁,在高并发场景下吞吐量通常比ArrayBlockingQueue更高。
  • 无界队列: 理论上是无限的,只要内存够就能一直放。
    • PriorityBlockingQueue 一个支持优先级排序的无界队列。元素必须实现Comparable接口,或者构造时传入Comparator。它出队的顺序是按优先级来的,不是先进先出
    • DelayQueue 一个很特殊的队列,里面放的是实现了Delayed接口的元素。每个元素都有个到期时间,只有到期了的元素才能被取出来。典型应用就是做缓存过期、定时任务调度。

2. 特殊功能的队列:

  • SynchronousQueue 这个队列非常特别,它不存储元素。每一个put操作必须等待一个take操作,就像“手递手”交接一样。它直接传递任务,效率很高,常用于线程池之间直接传递工作。CachedThreadPool用的就是它。
  • LinkedTransferQueueLinkedBlockingQueueSynchronousQueue的结合体。它多了个transfer方法,如果当前有消费者在等待,就直接把元素给消费者;如果没有,就入队,并且会阻塞直到该元素被消费掉。性能很好。


所以,我比较常记的是ArrayBlockingQueueLinkedBlockingQueuePriorityBlockingQueueDelayQueueSynchronousQueue这几个,它们各有各的应用场景。

拒绝策略有哪些?

拒绝策略是线程池的一个组成部分。当线程池的工作队列满了,并且所有线程也都达到最大线程数了,这时候再来新任务,就会触发拒绝策略。Java在ThreadPoolExecutor类里提供了4种内置的策略,都实现了RejectedExecutionHandler接口:

1. AbortPolicy(中止策略 - 默认策略):

  • 做法: 直接抛出一个RejectedExecutionException异常。
  • 感受: “比较粗暴,但好处是能让我们及时感知到系统出了饱和问题。”

2. CallerRunsPolicy(调用者运行策略):

  • 做法: 不抛弃任务,也不抛异常,而是将任务回退给调用者(提交任务的线程),让调用者自己去执行这个任务。
  • 感受: “这是一种‘负反馈’机制。提交任务的线程突然要自己去干活,它就忙起来了,自然就慢下来提交新任务了,给了线程池一个喘息的机会。这个策略在生产环境挺实用的,能平滑地降低流量。”

3. DiscardPolicy(丢弃策略):

  • 做法: 默默地把新提交的任务丢弃掉,不执行,也不给任何通知。
  • 感受: “风险比较大,因为任务丢了我们都不知道。除非是一些无关紧要的场景,否则一般不推荐。”

4. DiscardOldestPolicy(丢弃最老策略):

  • 做法:工作队列里排队时间最长的那个任务(队头的任务)丢掉,然后尝试把新任务再放进队列。
  • 感受: 这个策略有点‘喜新厌旧’。它可能丢弃掉一个非常重要的老任务,风险也挺高的,用的时候得想清楚业务上能不能接受。


当然,如果这四种都不满足需求,我们还可以自己实现RejectedExecutionHandler接口,来自定义拒绝策略,比如把拒绝的任务持久化到磁盘,或者记录日志后发个告警等等。

面试回答

Java中的阻塞队列主要有像ArrayBlockingQueue这种基于数组的有界队列,也有LinkedBlockingQueue这种基于链表可以无界的队列。还有一些特殊用途的,比如按优先级出队的PriorityBlockingQueue,做延时任务的DelayQueue,以及不存元素专门做传递的SynchronousQueue
 

关于拒绝策略,是线程池满载后的处理方式。默认的AbortPolicy会直接抛异常;CallerRunsPolicy会让提交任务的线程自己去执行,这个我们项目在用,能平滑流量;还有两种是直接丢弃任务或者丢弃队列中最老的任务。如果都不行,我们也可以根据业务自己实现一个。

如果小假的内容对你有帮助,请点赞评论收藏。创作不易,大家的支持就是我坚持下去的动力!

Read more

Docker Desktop for Mac 历史版本下载大全(macOS 10.15/11/12)

Docker Desktop for Mac 历史版本下载大全(macOS 10.15/11/12)

Docker Desktop for Mac 历史版本下载大全(macOS 10.15/11/12) 本文整理收集了各版本 macOS 系统对应的 Docker Desktop 历史版本下载链接,方便需要特定版本的用户下载使用。 各 macOS 版本对应的 Docker Desktop 最终支持版本 🍎 macOS Catalina (10.15) 最后一个支持版本 版本号:v4.15.0 下载链接: * Intel 芯片:https://desktop.docker.com/mac/main/amd64/93002/Docker.dmg 🍎 macOS Big Sur (11.x)

By Ne0inhk
Flutter 组件 test_reflective_loader 适配鸿蒙 HarmonyOS 实战:反射装载矩阵,构建规模化测试的自动化分发中枢

Flutter 组件 test_reflective_loader 适配鸿蒙 HarmonyOS 实战:反射装载矩阵,构建规模化测试的自动化分发中枢

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 组件 test_reflective_loader 适配鸿蒙 HarmonyOS 实战:反射装载矩阵,构建规模化测试的自动化分发中枢 前言 在鸿蒙(OpenHarmony)生态迈向大规模企业级应用、涉及深度组件解耦与多维功能验证的背景下,如何通过标准化的框架降低测试样板代码(Boilerplate)的维护成本,已成为决定项目迭代质效的“深水区工程”。在鸿蒙设备这类强调 AOT 编译性能与严苛环境隔离的移动终端上,如果依然依赖传统的手工挂载单元测试用例,由于由于随着业务规模膨胀而呈几何级增长的维护量,极易由于由于人为疏漏导致核心路径的测试脱节。 我们需要一种能够在开发期利用反射特性自动探测用例、支持面向对象继承复用且具备高度声明式语义的测试装载方案。 test_reflective_loader 为 Flutter 开发者引入了基于反射的测试组织范式。它允许通过定义标准的测试类(Test Classes),并在运行时自动识别带有特定前缀的测试

By Ne0inhk
Linux 源配置不用慌!CentOS/Ubuntu 源更新(含恢复)+Yum 操作 + Vim 入门,新手也能懂!

Linux 源配置不用慌!CentOS/Ubuntu 源更新(含恢复)+Yum 操作 + Vim 入门,新手也能懂!

✨ 孤廖:个人主页 🎯 个人专栏:《C++:从代码到机器》 🎯 个人专栏:《Linux系统探幽:从入门到内核》 🎯 个人专栏:《算法磨剑:用C++思考的艺术》 折而不挠,中不为下 文章目录 * 前言: * 正文: * 软件包管理器 * 1.什么是软件包 * 2. Linux软件⽣态 * 3. yum具体操作 * 查看软件包 * 安装软件 * 卸载软件 * Centos7更新yum源 * 1. 备份现有Yum源 * 2. 下载新的Yum源配置⽂件 * 3. 清理并⽣成缓存 * 4. 更新系统 * 5. 恢复原有Yum源(可选) * 6. 验证Yum源 * Ubuntu 更新apt源 * 1. 备份现有APT源 * 2. 直接下载新的APT源配置⽂

By Ne0inhk
Flutter 三方库 a2a 的鸿蒙化适配指南 - 实现高效的 Array-to-Array 结构转换、支持跨维度数据映射与集合内容深度克隆

Flutter 三方库 a2a 的鸿蒙化适配指南 - 实现高效的 Array-to-Array 结构转换、支持跨维度数据映射与集合内容深度克隆

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 a2a 的鸿蒙化适配指南 - 实现高效的 Array-to-Array 结构转换、支持跨维度数据映射与集合内容深度克隆 前言 在进行 Flutter for OpenHarmony 的大规模数据处理或图形计算开发时,经常需要对多维数组(嵌套列表)进行结构化调整。例如,将一个扁平化的传感器采样序列转换为 UI 渲染所需的网格坐标点集。a2a 是一个专门为 Array-to-Array 转换设计的极简工具库。它致力于通过声明式的 API 解决集合变换过程中的逻辑繁琐问题。本文将探讨如何在鸿蒙端利用该库提升集合操作的优雅度。 一、原原理性解析 / 概念介绍 1.1 基础原理 a2a 建立在一套强大的“映射算子(Mapping Operators)”之上。它获取输入数组,通过定义的投影(Project)

By Ne0inhk