线程池的discard-oldest策略和优先级堵塞队列共同使用的问题

最近在学习java并发相关的书时看到了这一段话:

This time, we’re using a bounded queue that can hold just two tasks. Here’s what happens when we submit these four tasks:

  • When the fourth task arrives, the discard-oldest policy removes the oldest task to make room for this new one

The discard-oldest policy and priority queues don’t play well together. Because the head of a priority queue has the highest priority, we may simply lose the most important task.

注意加粗的引用,意思就是discard-oldest策略抛弃的是堵塞队列中下一个将被执行的任务,而由于优先级队列中的下一个将被执行的任务是优先级最高的任务,所以discard-oldest策略和优先级堵塞队列共同使用的话,会造成将优先级最高的任务(也就是最重要的任务)抛弃的问题。

所以自己动手测试了一下discard-oldest策略和优先级堵塞队列共同使用代码,设置一个核心线程数和最大线程数都为2、拒绝策略为discard-oldest的线程池,设置一个容量为2的优先级队列PriorityBlockingQueue,然后执行5个有一定耗时任务。
由于线程池可容纳的最大任务数是线程数+队列容量=2+2=4个,所以5个任务进来的话,按照书里描述的应该是:

  1. 首先2个任务直接进入工作线程中运行
  2. 接着2个任务进入优先级队列中,并且按照优先级进行排序
  3. 最后1个任务进来时,由于线程和队列都满了,所以执行拒绝策略
  4. 拒绝策略抛弃队列中下一个将要执行的任务,所以应该将队列中优先级最高的任务抛弃,留出空位让给这最后一个策略

但是,具体测试过程中,随着实验进行,发现所有任务都被线程池执行了,根本没有触发拒绝策略。
查看PriorityBlockingQueue的源码才发现,PriorityBlockingQueue会自行扩容,具体方法是PriorityBlockingQueue.tryGrow(Object[] array, int oldCap)方法,当队列满了之后,再次调用添加元素的方法就会触发这个扩容,导致无论多少个任务提交给PriorityBlockingQueue它都会全盘接受,也就无法触发这个“将优先级最高的任务(也就是最重要的任务)抛弃”的场景。

所以有没有其他队列或者其他方法可以触发这个“将优先级最高的任务(也就是最重要的任务)抛弃”的场景呢?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值