HelloCoder HelloCoder
首页
《Java小白求职之路》
《小白学Java》
计算机毕设
  • 一些免费计算机资源
  • 脚手架工具
  • 《从0到1学习Java多线程》
  • 《从0到1搭建服务器》
随笔
关于作者
首页
《Java小白求职之路》
《小白学Java》
计算机毕设
  • 一些免费计算机资源
  • 脚手架工具
  • 《从0到1学习Java多线程》
  • 《从0到1搭建服务器》
随笔
关于作者
  • 《从0到1学习Java多线程》

    • (一)线程是什么
    • (二)Java线程与系统线程和生命周期
    • (三)Java线程创建方式
    • (四)为什么要使用线程池
    • (五)四种线程池底层详解
    • (六)ThreadPoolExecutor自定义线程池
    • (七)线程池的大小如何确定
    • (八)Callable和Runnable的区别
    • (九)线程池异常捕获
    • (十)线程池参数——workQueue用法
    • (十一)sleep(1)、sleep(0)和sleep(1000)的区别
    • (十二)yield、notify、notifyAll、sleep、join、wait的区别
    • (十三)synchronized
    • (十四)volatile
    • (十五)ThreadLocal的使用
    • (十六)ReentrantLock可重入锁
    • (十七)AtomicInteger
    • (十八)Worker线程管理
  • 《从0到1搭建服务器》

  • RPC

  • Spring源码

  • 《Java日志框架》

  • 可观测和监控

  • 玩转IDEA

  • 专栏
  • 《从0到1学习Java多线程》
#workQueue #线程池参数 #用法
码农阿雨
2022-05-26
目录

(十)线程池参数——workQueue用法

线程池参数的 workQueue 决定了缓存任务的排队策略,对于不同的业务场景,我们可以使用不同的排队策略。

我们只需要实现BlockingQueue 这个接口即可。

图片出处找不到了

JDK7 提供了 7 个阻塞队列。分别是:

ArrayBlockingQueue :一个由数组结构组成的有界阻塞队列。

LinkedBlockingQueue :一个由链表结构组成的有界阻塞队列。

PriorityBlockingQueue :一个支持优先级排序的无界阻塞队列。

DelayQueue:一个使用优先级队列实现的无界阻塞队列。

SynchronousQueue:一个不存储元素的阻塞队列。

LinkedTransferQueue:一个由链表结构组成的无界阻塞队列。

LinkedBlockingDeque:一个由链表结构组成的双向阻塞队列。

介绍一下常用的有三种workQueue

# 1. SynchronousQueue

SynchronousQueue没有容量,是无缓冲等待队列,是一个不存储元素的阻塞队列,会直接将任务交给消费者(即丢给空闲的线程去执行),必须等队列中的添加元素被消费后才能继续添加新的元素,否则会走拒绝策略,所以使用SynchronousQueue阻塞队列一般要求maximumPoolSizes为无界,避免线程拒绝执行操作。

插入元素到队列的线程被阻塞,直到另一个线程从队列中获取了队列中存储的元素。同样,如果线程尝试获取元素并且当前不存在任何元素,则该线程将被阻塞,直到线程将元素插入队列。

# 2. LinkedBlockingQueue

LinkedBlockingQueue如果不指定大小,默认值是 Integer.MAX_VALUE,就是说这个队列里面可以放 2^31-1 = 2147483647 个 任务,可以理解这就是无界队列。

源码在此:

public LinkedBlockingQueue() {
    this(Integer.MAX_VALUE);
}
@Native public static final int   MAX_VALUE = 0x7fffffff;

所以为了避免队列过大造成机器负载或者内存爆满的情况出现,我们在使用的时候建议手动传一个队列的大小。

与ArrayBlockingQueue不同的是,LinkedBlockingQueue内部分别使用了takeLock 和 putLock 对并发进行控制,也就是说,添加和删除操作并不是互斥操作,可以同时进行,这样也就可以大大提高吞吐量。

与之类似的是 LinkedBlockingDeque。

LinkedBlockingDeque: 使用双向队列实现的双端阻塞队列,双端意味着可以像普通队列一样FIFO(先进先出),可以像栈一样FILO(先进后出)

# 3. DelayQueue

DelayQueue是一个延迟队列,无界,队列中每个元素都有过期时间,当从队列获取元素时,只有过期元素才会出队列,而队列头部的元素是过期最快的元素。

能够准确的把握任务的执行时间,通常可以使用在:

  1. 定时任务调度,比如订单过期未支付自动取消

  2. 缓存

如何使用,可以参考这篇文章:https://blog.csdn.net/zhu_tianwei/article/details/53549653 (opens new window)

# 4. ArrayBlockingQueue

一个由数组支持的有界阻塞队列。

此队列按 FIFO(先进先出)原则对元素进行排序。一旦创建了这样的缓存区,就不能再增加其容量。

试图向已满队列中放入元素会导致操作受阻塞;

试图从空队列中提取元素将导致类似阻塞。

# 总结:

keepAliveTime和`maximumPoolSize 和 BlockingQueue 的类型均有关系。

如果BlockingQueue是无界的,那么永远不会触发maximumPoolSize,线程会一直往队列里面添加,自然keepAliveTime也就没有了意义。


参考:

  • 【细谈Java并发】谈谈LinkedBlockingQueue:https://blog.csdn.net/tonywu1992/article/details/83419448 (opens new window)
阅读全文
×

(为防止恶意爬虫)
扫码或搜索:HelloCoder
发送:290992
即可永久解锁本站全部文章

解锁
#workQueue#线程池参数#用法
上次更新: 2025-02-21 06:04:57
最近更新
01
《LeetCode 101》
02-21
02
IDEA、Golang、Pycharm破解安装
02-21
03
《LeetCode CookBook》
02-21
更多文章>
Theme by Vdoing | Copyright © 2020-2025 码农阿雨
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式