Timer & TimerTask

@(Base)[JDK, Timer, TimerTask]

Timer schedule(动词) task在后台执行。这个Task可能是只执行一次的task,也可能是按照一定规律执行的task。这也是JDK1.3提供的一个非常老的工具类

  • 对于每一个维持schedule的Timer对象来说,内部都只有一个线程顺序执行所有的task。所以每一个客户端提交的task需要尽可能快的完成。如果中间有个线程执行时间非常久,就会hogs起线程,然后面的线程都delay,这样会导致后续处理都很凌乱,让他们全部弄成一团在执行。

  • 当最后持有Timer引用的Object gc掉之后,并且所有的任务已经执行完了之后,timer的execution thread会gracefully终止(然后被垃圾回收)。这个时间可以变得无限长。这个execution线程并不是daemon的。所以他可以让你的application无法终止。如果调用方想要尽快终止程序,可以调用caller的cancel方法。

  • 如果timer的execute的线程异常终止,例如,当他的stop方法被调用的时候,当你再提交一个task进来的时候,就会抛出IllegalStateExcetpion,因为Timer的cancel方法已经被调用了。

  • 这个类是线程安全的。

  • 这个class通过Object.wait方法来调度任务。

注意: java 1.5 引入的并发包,中有一个ScheduledThreadPoolExecutor,是一个线程池,可以提供固定比率,或者时长的task。


Binary Heap

二叉堆是一种经过排序的完全二叉树,其中任一非终端节点的数据值均不大于(或不小于)其左孩子和右孩子节点的值。 —— 维基百科

  • 最大堆和最小堆是二叉堆的两种形式。
  • 最大堆:根结点的键值是所有堆结点键值中最大者。
  • 最小堆:根结点的键值是所有堆结点键值中最小者。
  • 最小堆,就是用于实现优先级队列的。
  • 对于节点N,那么他的两个子节点就是2n, 2n+1,n为数组位置

Insert

首先插入尾部,然后一直与index/2,比较交换。

  1. 6 --> [6]
  2. 9 --> [6,9]
  3. 4 --> [6,9,4] --> 4 < arr[3/2-1] --> change(arr[0], arr[2]) --> [4,9,6]
  4. 7 --> [4,9,6] --> 7 < arr[4/2-1] --> change(arr[1], arr[3]) --> [4,7,6,9]
  5. 5 --> [4,7,6,9,5] --> 5 < arr[5/2-1] --> change[arr[1], arr[4]] --> [4,5,6,9,7]
  6. 1 --> [4,5,6,9,7,1] --> 1 < arr[3-1] --> change[arr[2], arr[5]]

每次插入完成之后总能保证第一个是最小的,这个交换操称为fixUp,或者叫ShiftUp。

DELETE MIN

交换队头和队尾,然后删除队尾,然后比较index2, index+2 交换到最小。

  1. [1,5,4,9,7,6] --> [6,5,4,9,7,1] --> [6,5,4,9,7] --> [4,5,6,9,7]

    这个操作成为fixDown,或者ShiftDown。

PERFORMANCE

log(n) for add,removeMin,rescheduleMin.

constant time performance for the getMin operation.

LifeCycle

Constructor

新建TimerThread调度程序。执行mainLoop()

public void run() {
try { mainLoop(); }
finally { clean(); }
}

MainLoop

等待在队列上,有值唤醒后取出min操作.

while (true) {
sync(queue) {
while (queue.isEmpty()) { // avoid furious weak up
queue.wait(); // point 1
}
task = queue.getMain();
sync (task) { // avoid out-side modify // point 2
// do some cancel check
if (taskFired = (executionTime <= currentTime)) {
queue.rescheduleMin(); // or queue.removeMin();
}
}
if (!taskFired) { // point3
queue.wait(executionTime)
}
}
if (taskFired) { // point4
task.run()
}
}

这段小代码还是很精悍。

  • Point 1: 利用queue对象的wait/notify做了通知模型,当有新任务的时候就会唤醒
  • Point 2: 锁定task对象,避免task对象的内部状态被别人更改,当确定完状态之后,外部更改也就无效了,并且只是改状态的时候加锁
  • Point 3: 当前task的执行时间还不到的时候,挂在queue对象上睡,为什么挂在queue对象上睡呢,这一点很重要,当有新任务进来的时候可以响应到。
  • Point 4: 唤醒之后,如果还不够时间,就进入下一次循环。否则如果够了的话就执行。

schedule

sync (queue) {
sync(task) {
// change state and nextTime
}
queue.add(task)
if (queue.getMin() == task) {
queue.notify();
}
}

cancel Timer

synchronized(queue) {
thread.newTasksMayBeScheduled = false;
queue.clear();
queue.notify(); // In case queue was already empty.
}

cancel one Time Task

sync(this.lock) {
this.state = CANCEL;
}

purge

清除所有已经被cancel的task,一般小程序都不需要使用。

sync (queue) {
for (item in queue) {
queue.remove(item); // change current with the last
}
reindex();
}

JDK Timer & TimerTask的更多相关文章

  1. Timer&TimerTask原理分析

    转载地址,请珍惜作者的劳动成果,转载请注明出处:http://www.open-open.com/lib/view/open1337176725619.html 如果你使用Java语言进行开发,对于定 ...

  2. Spring + JDK Timer Scheduler Example--reference

    http://www.mkyong.com/spring/spring-jdk-timer-scheduler-example/ In this example, you will use Sprin ...

  3. 线程 Timer TimerTask 计时器 定时任务 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  4. Timer TimerTask schedule scheduleAtFixedRate

    jdk 自带的 timer 框架是有缺陷的, 其功能简单,而且有时候它的api 不好理解. import java.util.Date; import java.util.Timer; import ...

  5. 使用Handler和Timer+Timertask实现简单的图片轮播

    布局文件就只放了一个简单的ImageView,就不展示了. 下面是Activity package com.example.administrator.handlerthreadmessagedemo ...

  6. Java Timer, TimerTask

    参考:http://batitan.iteye.com/blog/253483 TimerTask 就是一个run 方法,里边有些操作: Timer 是个线程,按各种调度方法(Timer.schedu ...

  7. Android 中执行定时任务 Timer + TimerTask

    1. new Timer().schedule(new TimerTask() { @Override public void run() { //任务代码 } }, 0, 5000);

  8. Timer,TimerTask通过程序计数器实现的定时任务

    1.程序计数器 程序计数器(Program Counter Register)是一块较小的内存空间,它的作用可以看 做是当前线程所执行的字节码的行号指示器.在虚拟机的概念模型里(仅是概念模型, 各种虚 ...

  9. Handler Timer TimerTask ScheduledExecutor 循环任务解析

    使用Handler执行循环任务 private Handler handler = new Handler(); private int mDelayTime = 1000; private Runn ...

随机推荐

  1. 基于Verilog的串口发送程序

    一.模块框图及基本思路 tx_bps_module:波特率时钟产生模块 tx_control_module:串口发送的核心控制模块 tx_module:前两个模块的组合 control_module: ...

  2. Python2和Python3关于reload()用法的区别

    Python2 中可以直接使用reload(module)重载模块. Pyhton3中需要使用如下两种方式: 方式(1) >>> from imp >>> imp. ...

  3. Javascript 蛤蟆可以吃队友,也可以吃对手 比较字符串

    Javascript 蛤蟆可以吃队友,也可以吃对手 比较字符串 function mutation(arr) { for(var i = 0; i < arr[1].length; i++) { ...

  4. SUID、SGID、粘滞位

    粘滞位(Stikybit) +t,只有用户自己可以删除自己创建文件,其他用户只能查看,不能删除.        1:创建两个用户  useradd oo                         ...

  5. 淘宝客知道这几个ID,收入将会提高50%

    基础问题天天说,天天有人问.这篇文章写点基础的.特别对新手的帮助会很大哦. 1,PID,做淘宝客不知道PID,赚到钱也会被冻结. 如何手动获取PID 2,单品ID,淘宝商品的唯一识别编号,和身份证一样 ...

  6. flask-appbuilder +echarts 展示数据笔记

    pip install flask-appbuilder fabmanager create-app cd newapp fabmanager create-admin fabmanager run ...

  7. windows下使用vscode编写运行以及调试C/C++

    未经允许,禁止转载,唯一出处:tangming博客园 最后更新于2019年4月4日: 多次更新,内容较多,篇幅较大,但如果是喜欢visual stdio code这款编辑器的话建议仔细阅读,有疑问的地 ...

  8. 作业-JSP简单入门

    说明 本次作业不打分,仅作为大家自学的指导. 本次实验内容以"JSP实验参考文件"为主. 参考资料 Java教学问卷调查,有什么想说的,请尽情投票吧! 反射实验参考文件 JSP实验 ...

  9. 源码编译、安装net-snmp的方法和遇到的问题

    本文参考地址:http://blog.163.com/qiushuhui1989@126/blog/static/270110892014119113421364/ 1. 源码下载 # wget ht ...

  10. IIC时序详解

    Verilog IIC通信实验笔记 Write by Gianttank 我实验的是 AT24C08的单字节读,单字节写,页读和页写,在高于3.3V系统中他的通信速率最高400KHZ的,我实验里用的是 ...