DelayedWorkQueue:

DelayedWorkQueue实现了BlockingQueue接口,因此其可以作为线程池的任务队列。BlockingQueue的主要属性有以下几个:

  • private RunnableScheduledFuture[] queue:作为最小堆的实现数组,主要存储ScheduledFutureTask任务列表。
  • private final ReentrantLock lock:可重入锁,保证队列数据多线程下的一致性。
  • private int size = 0:队列中任务总数
  • private Thread leader = null:主要是为了尽量减少队列头任务执行的时间,这个字段将在tack()函数中具体讲解其用法。
  • private final Condition available = lock.newCondition():锁条件变量。

DelayedWorkQueue最主要的两个方法就是take()和offer()方法。offer()方法是向队列里新增一个任务,take是从延迟队列中取出当前需要执行的任务。

    public boolean offer(Runnable x) {
if (x == null)
throw new NullPointerException();
RunnableScheduledFuture e = (RunnableScheduledFuture)x;
final ReentrantLock lock = this.lock;
lock.lock();
try {
int i = size;
if (i >= queue.length)
//队列满时,扩容
grow();
size = i + 1;
if (i == 0) {
queue[0] = e;
setIndex(e, 0);
} else {
//将新加入的任务按照最小堆排序规则进行排序
siftUp(i, e);
}
//当队列只有一个元素时,将leader置为null,并发送消息唤醒take或offer操作
if (queue[0] == e) {
leader = null;
available.signal();
}
} finally {
lock.unlock();
}
return true;
}

上述为offer操作,用于向队列中插入任务,所有插入的准则都是按照最小堆准则,保证堆顶元素为最先需要执行的任务。

    public RunnableScheduledFuture take() throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();
try {
for (;;) {
//获取堆顶元素,也就是需要现在执行的任务
RunnableScheduledFuture first = queue[0];
if (first == null)
//如果队列中没有元素则等待,对应offer()中的available.signal();
available.await();
else {
long delay = first.getDelay(TimeUnit.NANOSECONDS);
if (delay <= 0)
return finishPoll(first);
else if (leader != null)
//如果leader不为null说明该线程正在执行其他操作(例如offer)
available.await();
else {
Thread thisThread = Thread.currentThread();
//将leader置为当前线程
leader = thisThread;
try {
//等待直到该线程需要执行的时间点,在下一个循环中获取当前任务
available.awaitNanos(delay);
} finally {
//无论什么操作,在返回前必须将leader置为null
if (leader == thisThread)
leader = null;
}
}
}
}
} finally {
if (leader == null && queue[0] != null)
available.signal();
lock.unlock();
}
}

ScheduleThreadPoolExecutor源码分析(二)的更多相关文章

  1. Fresco 源码分析(二) Fresco客户端与服务端交互(1) 解决遗留的Q1问题

    4.2 Fresco客户端与服务端的交互(一) 解决Q1问题 从这篇博客开始,我们开始讨论客户端与服务端是如何交互的,这个交互的入口,我们从Q1问题入手(博客按照这样的问题入手,是因为当时我也是从这里 ...

  2. ScheduleThreadPoolExecutor源码分析

    ScheduleThreadPoolExecutor源码分析(一) Java中ScheduleThreadPoolExecutor主要用于执行延迟任务或者按照一定的频率执行任务.其中scheduleA ...

  3. 框架-springmvc源码分析(二)

    框架-springmvc源码分析(二) 参考: http://www.cnblogs.com/leftthen/p/5207787.html http://www.cnblogs.com/leftth ...

  4. Tomcat源码分析二:先看看Tomcat的整体架构

    Tomcat源码分析二:先看看Tomcat的整体架构 Tomcat架构图 我们先来看一张比较经典的Tomcat架构图: 从这张图中,我们可以看出Tomcat中含有Server.Service.Conn ...

  5. 十、Spring之BeanFactory源码分析(二)

    Spring之BeanFactory源码分析(二) 前言 在前面我们简单的分析了BeanFactory的结构,ListableBeanFactory,HierarchicalBeanFactory,A ...

  6. Vue源码分析(二) : Vue实例挂载

    Vue源码分析(二) : Vue实例挂载 author: @TiffanysBear 实例挂载主要是 $mount 方法的实现,在 src/platforms/web/entry-runtime-wi ...

  7. 多线程之美8一 AbstractQueuedSynchronizer源码分析<二>

    目录 AQS的源码分析 该篇主要分析AQS的ConditionObject,是AQS的内部类,实现等待通知机制. 1.条件队列 条件队列与AQS中的同步队列有所不同,结构图如下: 两者区别: 1.链表 ...

  8. ABP源码分析二:ABP中配置的注册和初始化

    一般来说,ASP.NET Web应用程序的第一个执行的方法是Global.asax下定义的Start方法.执行这个方法前HttpApplication 实例必须存在,也就是说其构造函数的执行必然是完成 ...

  9. spring源码分析(二)Aop

    创建日期:2016.08.19 修改日期:2016.08.20-2016.08.21 交流QQ:992591601 参考资料:<spring源码深度解析>.<spring技术内幕&g ...

  10. ConcurrenHashMap源码分析(二)

    本篇博客的目录: 一:put方法源码 二:get方法源码 三:rehash的过程 四:总结 一:put方法的源码 首先,我们来看一下segment内部类中put方法的源码,这个方法它是segment片 ...

随机推荐

  1. Linux Kernel ‘perf’ Utility 本地提权漏洞

    漏洞名称: Linux Kernel ‘perf’ Utility 本地提权漏洞 CNNVD编号: CNNVD-201309-050 发布时间: 2013-09-09 更新时间: 2013-09-09 ...

  2. ♫【模式】自定义函数(self-defining function)

    <JavaScript模式> /** * 如果创建了一个新函数并且将其分配给保存了另外函数的同一个变量,那么就以一个新函数覆盖旧函数. * 在某种程度上,回收旧函数指针以指向一个新函数.而 ...

  3. OA请假流程 -- 编码

    OA请假流程 -- 编码 凡是内容不会发生变化的,都要写在xml配置文件中.需要定义如下内容: <process>标签 id英文命名 和 name 中文命名,然后只要与该流程相关的资源均以 ...

  4. Spark PySpark数据类型的转换原理—Writable Converter

    Spark目前支持三种开发语言:Scala.Java.Python,目前我们大量使用Python来开发Spark App(Spark 1.2开始支持使用Python开发Spark Streaming ...

  5. (转载)linux中shell变量

    (转载)http://blog.csdn.net/zahuopuboss/article/details/8633891 为使shell编程更有效,系统提供了一些shell变量.shell变量可以保存 ...

  6. vijosP1285 佳佳的魔法药水

    vijosP1285 佳佳的魔法药水 链接:https://vijos.org/p/1285 [思路] 图论思想. 很巧妙. 如A+B=C,将AB之间连边,边权为C,用以找相连物品与合成物. 用Dij ...

  7. OpenOffice 服务开机启动

    1.准备以下软件 OpenOffice3.0,Windows Resource Kit Tools 分别默认安装 2.打开Windows Resource Kit Tools -> Comman ...

  8. matches()方法

    java.lang包中的String类和java.util.regex包中的Pattern,Matcher类中都有matches()方法,都与正则表达式有关.下面我分别举例:(字符串:"ab ...

  9. sql Server 发送邮件 错误类型及原因

    设置警报         在[常规项]中做以下设置 新建警报 设置警报名称 选择数据库 选择严重性     在[响应项]中可以做以下设置 选择要邮件通知的操作员 可以设置执行一个警报作业    在选项 ...

  10. K倍动态减法游戏

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=2580 #include <iostream> #include <string.h> ...