JAVA随笔篇一(Timer源代码分析和scheduleAtFixedRate的使用)
写完了基础篇,想了非常久要不要去写进阶篇。去写JSP等等的用法。最后决定先不去写。由于自己并非JAVA方面的大牛。眼下也在边做边学,所以决定先将自己不懂的拿出来学并记下来。
Timer是Java自带的java.util.Timer类,通过调度一个java.util.TimerTask任务。这样的方式能够让程序依照某一个频度运行。
1、Timer类的源代码分析:
public class Timer {
/**
* The timer task queue. This data structure is shared with the timer
* thread. The timer produces tasks, via its various schedule calls,
* and the timer thread consumes, executing timer tasks as appropriate,
* and removing them from the queue when they're obsolete.
*/
private TaskQueue queue = new TaskQueue();
/**
* The timer thread.
*/
private TimerThread thread = new TimerThread(queue);
首先Timer类定义了两个私有变量TaskQueue和TimerThread。
TaskQueue:Timer类定义了一个定时器任务队列。一个TimerTasks的优先级队列。
class TaskQueue {
/**
* Priority queue represented as a balanced binary heap: the two children
* of queue[n] are queue[2*n] and queue[2*n+1]. The priority queue is
* ordered on the nextExecutionTime field: The TimerTask with the lowest
* nextExecutionTime is in queue[1] (assuming the queue is nonempty). For
* each node n in the heap, and each descendant of n, d,
* n.nextExecutionTime <= d.nextExecutionTime.
*/
private TimerTask[] queue = new TimerTask[128];
TimerThread:Timer类的任务运行线程。从Thread类继承。以TaskQueue为參数。
在使用Timer类,首先new一个Timer对象,然后利用scheduleXXX函数运行任务,首先分析Timer对象构造过程:
public Timer() {
this("Timer-" + serialNumber());
}
public Timer(boolean isDaemon) {
this("Timer-" + serialNumber(), isDaemon);
}<span style="white-space:pre"> </span>
public Timer(String name) {
thread.setName(name);
thread.start();
}
public Timer(String name, boolean isDaemon) {
thread.setName(name);
thread.setDaemon(isDaemon);
thread.start();
}
能够看出,Timer在构造对象过程中,须要启动一个TimerThread线程,因此能够推測,TimerThread线程和Timer对象共同维护一个TaskQueue,利用TaskQueue进行信息传递。
接下来看scheduleXXX函数。全部的scheduleXXX函数都须要调用sched方法,
private void sched(TimerTask task, long time, long period) {
if (time < 0)
throw new IllegalArgumentException("Illegal execution time.");
synchronized(queue) {
if (!thread.newTasksMayBeScheduled)
throw new IllegalStateException("Timer already cancelled.");
synchronized(task.lock) {
if (task.state != TimerTask.VIRGIN)
throw new IllegalStateException(
"Task already scheduled or cancelled");
task.nextExecutionTime = time;
task.period = period;
task.state = TimerTask.SCHEDULED;
}
queue.add(task);
if (queue.getMin() == task)
queue.notify();
}
}
这里首先介绍一下TimerTask类:
public abstract class TimerTask implements Runnable {
/**
* This object is used to control access to the TimerTask internals.
*/
final Object lock = new Object();
TimerTask类实现了Runnable接口,待运行的任务置于run()中。在构造定时任务的时候。从TimerTask继承并实现run方法。并创建任务传给scheduleXXX方法。
从sched方法中能够看出,sched方法中须要操作TaskQueue队列,而TimerThread线程启动之后相同使用这个队列,这就必须使用synchronized保证多线程安全使用。
2、scheduleXXX的使用:
Timer类的原理非常easy,能够使用的函数不多。以下将所有列出。
(1)void java.util.Timer.schedule(TimerTask task, long delay):多长时间(毫秒)后运行任务
(2)void java.util.Timer.schedule(TimerTask task, Date time):设定某个时间运行任务
(3)void java.util.Timer.schedule(TimerTask task, long delay, long period):delay时间后開始运行任务,并每隔period时间调用任务一次。
(4)void java.util.Timer.schedule(TimerTask task, Date firstTime, long period):第一次在指定firstTime时间点运行任务,之后每隔period时间调用任务一次。
(5)void java.util.Timer.scheduleAtFixedRate(TimerTask task, long delay, long period):delay时间后開始运行任务。并每隔period时间调用任务一次。
(6)void java.util.Timer.scheduleAtFixedRate(TimerTask task, Date firstTime, long period):第一次在指定firstTime时间点运行任务。之后每隔period时间调用任务一次。
(7)void java.util.Timer.cancel():终止该Timer
(8)boolean java.util.TimerTask.cancel():终止该TimerTask
这些scheduleXXX方法中,除了(1)(2)外,其它都能够反复调用任务,基本的区别就是schedule和scheduleAtFixedRate的区别。
schedule()方法更注重保持间隔时间的稳定:保障每隔period时间可调用一次。
scheduleAtFixedRate()方法更注重保持运行频率的稳定:保障多次调用的频率趋近于period时间。假设某一次调用时间大于period,下一次就会尽量小于period。以保障频率接近于period
3、Timer类的使用示列
首先创建一个任务:
<pre name="code" class="java">import java.util.TimerTask;
public class MyTask extends TimerTask{
private int id;
public MyTask(int id){
this.id = id;
}
public void run(){
System.out.println("线程" + id + ":正在运行");
//System.gc();
}
}
main函数代码:
import java.util.Date;
import java.util.Timer;
public class Test{
public static void main(String[] args){
Timer timer = new Timer();
timer.schedule(new MyTask(1), 5000);// 5秒后启动任务
MyTask secondTask = new MyTask(2);
timer.schedule(secondTask, 1000, 3000);
// 1秒后启动任务,以后每隔3秒运行一次线程
Date date = new Date();
timer.schedule(new MyTask(3), new Date(date.getTime() + 1000));
// 以date为參数,指定某个时间点运行线程
// timer.cancel();
// secondTask.cancel();
System.out.println("main thread 结束!");
}
}
JAVA随笔篇一(Timer源代码分析和scheduleAtFixedRate的使用)的更多相关文章
- Java中arraylist和linkedlist源代码分析与性能比較
Java中arraylist和linkedlist源代码分析与性能比較 1,简单介绍 在java开发中比較经常使用的数据结构是arraylist和linkedlist,本文主要从源代码角度分析arra ...
- Java集合系列之TreeMap源代码分析
一.概述 TreeMap是基于红黑树实现的.因为TreeMap实现了java.util.sortMap接口,集合中的映射关系是具有一定顺序的,该映射依据其键的自然顺序进行排序或者依据创建映射时提供的C ...
- Android4.42-Setting源代码分析之蓝牙模块Bluetooth(下)
接着上一篇Android4.42-Settings源代码分析之蓝牙模块Bluetooth(上) 继续蓝牙模块源代码的研究 THREE.蓝牙模块功能实现 switch的分析以及本机蓝牙重命名和可见性的分 ...
- Android4.42-Settings源代码分析之蓝牙模块Bluetooth(上)
继上一篇Android系统源代码剖析(一)---Settings 接着来介绍一下设置中某个模块的源代码.本文依然是基于Android4.42源代码进行分析,分析一下蓝牙模块的实现.建议大致看一下关于S ...
- java同步包种ArrayBlockingQueue类的分析与理解
前言: ArrayBlockingQueue类是一个堵塞队列.重要用于多线程操作的条件. 一,官方解释 一个建立在数组之上被BlockingQueue绑定的堵塞队列.这个队列元素顺序是先进先出.队列的 ...
- Spark SQL 源代码分析系列
从决定写Spark SQL文章的源代码分析,到现在一个月的时间,一个又一个几乎相同的结束很快,在这里也做了一个综合指数,方便阅读,下面是读取顺序 :) 第一章 Spark SQL源代码分析之核心流程 ...
- Java提高篇——通过分析 JDK 源代码研究 Hash 存储机制
HashMap 和 HashSet 是 Java Collection Framework 的两个重要成员,其中 HashMap 是 Map 接口的常用实现类,HashSet 是 Set 接口的常用实 ...
- Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6642463 在前面几篇文章中,我们详细介绍了A ...
- Monkey源代码分析番外篇之Android注入事件的三种方法比較
原文:http://www.pocketmagic.net/2012/04/injecting-events-programatically-on-android/#.VEoIoIuUcaV 往下分析 ...
随机推荐
- 一起写框架-Ioc内核容器的实现-基础API的定义(三)
Ioc内核要解决的问题 1.被调用方,在程序启动时就要创建好对象,放在一个容器里面. 2.调用方使用一个接口或类的引用(不用使用new),就可以创建获得对象. 解决这个两个问题的思路 1.定义一个对象 ...
- localstorage本地定时缓存
在做一个网站时,起初直接就是从服务器获取数据进行交互,没有用一些本地缓存做优化,项目做下来就特别卡,并且对服务器造成了很大的压力,经过请教,查询,找到这样一个定时缓存的例子.html5定时缓存,从数据 ...
- js的call() ,apply() 两种方法的区别和用法,最白话文的解释,让枯燥滚粗!
百度了一圈calll()函数和apply()函数,感觉还是糊里糊涂 正好我前几天刚又重新翻了一遍 那本 600多页 的圣经书,我习惯时不时的去打下基础,只是为了用来装逼,给人讲解....(我是有多蛋疼 ...
- Python之uuid模块
UUID是128位的全局唯一标识符,通常由32字节的字符串表示. 它可以保证时间和空间的唯一性,也称为GUID,全称为: UUID —— Universally Unique IDentifier P ...
- C#操作防火墙控制电脑某些软件联网
问题: 目前公司软件刚由单机软件更改为联网软件,许多客户反映希望能够有一个功能来控制电脑上某些必用软件,如qq,公司软件联网,而其他不必要的如网页,游戏等软件不允许联网,于是向公司反映希望可以有一个功 ...
- ABP module-zero +AdminLTE+Bootstrap Table+jQuery权限管理系统第十三节--RBAC模式及ABP权限管理(附送福利)
ABP+AdminLTE+Bootstrap Table权限管理系统一期 Github:https://github.com/Jimmey-Jiang/ABP-ASP.NET-Boilerplate- ...
- 自动化之路 python psutil模块 收集硬件信息
一.psutil模块 1. psutil是一个跨平台库,能够轻松实现获取系统运行的进程和系统利用率(包括CPU.内存.磁盘.网络等)信息.它主要应用于系统监控,分析和限制系统资源及进程的管理.它实现了 ...
- Python基础-数据类型和变量
数据类型 python中包含6种标准数据类型:1.Number 数值类型2.String 字符串类型3.List 列表类型4.Tuple 元祖类型5.Dict 字典类型6.Set 集合类型 注意:除了 ...
- AIO5打印样式函数说明
函数名称 描述 _RM_Column 返回当前栏目数. _RM_Line 返回数据行数(从分组的起始位置开始) _RM_LineThough 返回数据行数(从报表的起始位置开始) _RM_Page 返 ...
- JAVA 异常向上抛和向下抛的优劣势
向上抛: 优点:向上抛出异常,下面代码清秀: 缺点:不能直接看出抛出异常的代码: 向下抛: 优点:能直接看到出现异常的代码,方便查找,显得严谨: 缺点:代码太多: 总结:尽量向上抛,代码量减少,同意解 ...