ScheduleThreadPoolExecutor源码分析(二)
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源码分析(二)的更多相关文章
- Fresco 源码分析(二) Fresco客户端与服务端交互(1) 解决遗留的Q1问题
4.2 Fresco客户端与服务端的交互(一) 解决Q1问题 从这篇博客开始,我们开始讨论客户端与服务端是如何交互的,这个交互的入口,我们从Q1问题入手(博客按照这样的问题入手,是因为当时我也是从这里 ...
- ScheduleThreadPoolExecutor源码分析
ScheduleThreadPoolExecutor源码分析(一) Java中ScheduleThreadPoolExecutor主要用于执行延迟任务或者按照一定的频率执行任务.其中scheduleA ...
- 框架-springmvc源码分析(二)
框架-springmvc源码分析(二) 参考: http://www.cnblogs.com/leftthen/p/5207787.html http://www.cnblogs.com/leftth ...
- Tomcat源码分析二:先看看Tomcat的整体架构
Tomcat源码分析二:先看看Tomcat的整体架构 Tomcat架构图 我们先来看一张比较经典的Tomcat架构图: 从这张图中,我们可以看出Tomcat中含有Server.Service.Conn ...
- 十、Spring之BeanFactory源码分析(二)
Spring之BeanFactory源码分析(二) 前言 在前面我们简单的分析了BeanFactory的结构,ListableBeanFactory,HierarchicalBeanFactory,A ...
- Vue源码分析(二) : Vue实例挂载
Vue源码分析(二) : Vue实例挂载 author: @TiffanysBear 实例挂载主要是 $mount 方法的实现,在 src/platforms/web/entry-runtime-wi ...
- 多线程之美8一 AbstractQueuedSynchronizer源码分析<二>
目录 AQS的源码分析 该篇主要分析AQS的ConditionObject,是AQS的内部类,实现等待通知机制. 1.条件队列 条件队列与AQS中的同步队列有所不同,结构图如下: 两者区别: 1.链表 ...
- ABP源码分析二:ABP中配置的注册和初始化
一般来说,ASP.NET Web应用程序的第一个执行的方法是Global.asax下定义的Start方法.执行这个方法前HttpApplication 实例必须存在,也就是说其构造函数的执行必然是完成 ...
- spring源码分析(二)Aop
创建日期:2016.08.19 修改日期:2016.08.20-2016.08.21 交流QQ:992591601 参考资料:<spring源码深度解析>.<spring技术内幕&g ...
- ConcurrenHashMap源码分析(二)
本篇博客的目录: 一:put方法源码 二:get方法源码 三:rehash的过程 四:总结 一:put方法的源码 首先,我们来看一下segment内部类中put方法的源码,这个方法它是segment片 ...
随机推荐
- sql server知道触发器名如何查看里面代码
以sqlserver2008为例,可以写代码查看,也可以通过SQL Server Manager Studio工具的树形列表查看. 一.代码查看: 直接在SQL Server Manager Stud ...
- URAL1079
Problem E Time Limit : 4000/2000ms (Java/Other) Memory Limit : 32768/16384K (Java/Other) Total Sub ...
- js中singleton模式解析及运用
singleton模式,又名单例模式.顾名思义,就是只能实例化一次的类(javascript中没有真正的类,我们通常用函数来模拟类,习惯称之为"伪类").具体地说,singleto ...
- 关于JNI程序中引用另外一个lib
我最近在写一个j2se的程序,我用的是开源的org.amse.ys.zip包里的代码,这部分代码是在FBReaderJ里抽取的,但是其中包含了一些native的方法,需要用的zlib库,而FBRead ...
- mac上的键盘生活——神级输入法:鼠须管
好吧,我是今天才知道这个无敌的输入法有多么强悍,传说中的神级输入法,鼠须管~ 在这之前我都一直是用的搜狗输入法,因为以前在win下就一直都用的是搜狗输入法,怎么说,各种国产的输入法做的还是比较有良心的 ...
- TCP HTTP 详细内存分析 & time_wait setsockopt
http://www.kegel.com/c10k.html#nb.edge http://www.chinasb.org/archives/2012/11/4954.shtml UDP协议:发送进程 ...
- BNUOJ 34985 Elegant String 2014北京邀请赛E题 矩阵快速幂
题目链接:http://acm.bnu.edu.cn/bnuoj/problem_show.php?pid=34985 题目大意:问n长度的串用0~k的数字去填,有多少个串保证任意子串中不包含0~k的 ...
- XMPPFrameWork IOS 开发(六)聊天室
原始地址:XMPPFrameWork IOS 开发(六)聊天室 聊天室 //初始化聊天室 XMPPJID *roomJID = [XMPPJID jidWithString:ROOM_JID]; xm ...
- 快速幂模m算法
给你三个数,a,b,m 求a^b%m的值. 如果b过大,用普通的快速幂会超时. 所以将b=2^0*b0+2^1*b+b1...... 然后,你们利用初中的知识就知道怎么做了. 继续,上代码. #inc ...
- PPT五大插件汇总下载
收集总结一下PPT制作中常用到的插件/应用,希望能帮到大家. 1.Nordri Tools NT插件是由Nordri公司开发的PPT插件,功能强大,简单易上手,设计偷懒必备神器.我们可以看看它有哪些功 ...