ScheduledThreadPoolExecutor原理解析-DelayedWorkQueue

DelayedWorkQueue是ScheduledThreadPoolExecutor使用的一种基于小根堆的数据结构,用于存储ScheduledFutureTask。队列中的元素按延迟时间排序,头元素最先执行。队列的插入和删除操作通过siftUp()和siftDown()维护堆的性质。此外,文章详细介绍了添加和移除任务的逻辑,包括领导线程的概念以及take()和poll()方法的实现,这些方法考虑了任务的延迟时间和线程等待策略。

大家好,我是半夏之沫 😁😁 一名金融科技领域的JAVA系统研发😊😊
我希望将自己工作和学习中的经验以最朴实最严谨的方式分享给大家,共同进步👉💓👈
👉👉👉👉👉👉👉👉💓写作不易,期待大家的关注和点赞💓👈👈👈👈👈👈👈👈
👉👉👉👉👉👉👉👉💓关注微信公众号【技术探界】 💓👈👈👈👈👈👈👈👈


前言

DelayedWorkQueueScheduledThreadPoolExecutor线程池使用的任务阻塞队列。DelayedWorkQueue是基于小根堆实现的延时优先级队列,队列中的元素就是ScheduledFutureTask,因此DelayedWorkQueue的队列头节点任务总是最优先被执行的任务。本篇文章将对DelayedWorkQueue的实现原理进行分析。

正文

先看一下DelayedWorkQueue的字段,如下所示。

static class DelayedWorkQueue extends AbstractQueue<Runnable>
	implements BlockingQueue<Runnable> {
   
   

	// 堆数组的初始大小
	private static final int INITIAL_CAPACITY = 16;
	
	// 堆数组,数组中的元素实际上是ScheduledFutureTask
	private RunnableScheduledFuture<?>[] queue =
		new RunnableScheduledFuture<?>[INITIAL_CAPACITY];
	
	private final ReentrantLock lock = new ReentrantLock();
	
	// 延时队列元素个数
	private int size = 0;

	// 在延时队列头等待任务的领导线程
	private Thread leader = null;

	private final Condition available = lock.newCondition();
	
	......
	
}

特别说明一下leader字段和available字段,首先是leader字段,表示在延时队列头等待任务的第一个线程,即如果延时队列头的任务需要被执行时,这个任务会被leader字段指向的线程获得。同时所有在延时队列头等待任务的线程,均会在available上进入等待状态,并且在延时队列头的任务需要被执行时或者延时队列头的任务被更新时唤醒所有在available上等待的线程。

已知DelayedWorkQueue是一个基于小根堆实现的延时优先级队列,那么往DelayedWorkQueue中插入和删除任务后,均需要保持堆的性质,在DelayedWorkQueue中,主要是siftUp()siftDown()这两个方法来保持堆的性质,siftUp()是用于往DelayedWorkQueue中插入任务时来保持堆的性质,而siftDown()是用于DelayedWorkQueue弹出任务后保持堆的性质,其实现如下。

siftUp()实现如下所示。

private void siftUp(int k, RunnableScheduledFuture<?> key) {
   
   
	while (k > 0) {
   
   
		// 计算父节点索引
		int parent = (k - 1) >>> 1;
		RunnableScheduledFuture<?> e = queue[parent];
		// 将插入元素与父节点元素进行比较
		// 如果插入元素大于等于父节点元素,则循环结束
		if (key.compareTo(e) >= 
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

半夏之沫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值