Timer定时器
源码:
public class Timer {
private final TaskQueue queue = new TaskQueue();//定时器队列
private final TimerThread thread = new TimerThread(queue);//定时器线程
首先看看TaskQueue 和 TimerThread
TaskQueue
class TaskQueue {
//是timer中的类 ,属性有TimerTask数组,初始大小是128,当容量不够,扩容两被
private TimerTask[] queue = new TimerTask[128];
添加和扩容方法
void add(TimerTask task) {
// Grow backing store if necessary
if (size + 1 == queue.length)
queue = Arrays.copyOf(queue, 2*queue.length);//每次扩容两倍,初始容量为128
queue[++size] = task;
fixUp(size);//按照定制时间往前移动
}
按定时时间进行,排序方法
private void fixUp(int k)
private void fixDown(int k)
数组最基本单元 TimerTask
public abstract class TimerTask implements Runnable {
final Object lock = new Object();//就是用来控制线程安全的,没有其他意义,因为每次只有一个线程可以得到该对象
int state = VIRGIN;//运行状态
// VIRGIN 未执行
// SCHEDULED 如果是可重复的,就是安排继续执行,如果是单个任务,就是还没有执行
// EXECUTED 已经执行或者还没有执行结束
// CANCELLED 取消
long nextExecutionTime;//下一次执行时间
long period = 0;//重复执行间隔
public boolean cancel() {
synchronized(lock) {//lock控制访问
boolean result = (state == SCHEDULED);
state = CANCELLED;
return result;//如果此方法阻止了一个或多个预定的执行发生,返回true;如果成功阻止再次发生,返回true
}
}
public long scheduledExecutionTime() {//最近计划执行时间
synchronized(lock) {
return (period < 0 ? nextExecutionTime + period
: nextExecutionTime - period);
}
}
TimerThread
class TimerThread extends Thread {
boolean newTasksMayBeScheduled = true;//是否制定了新的计划任务
private TaskQueue queue;
重写run方法
public void run() {
try {
mainLoop();
} finally {
// Someone killed this Thread, behave as if Timer cancelled
synchronized(queue) {//执行结束以后清理 走到这里,说明任务全部执行结束
newTasksMayBeScheduled = false;
queue.clear(); // Eliminate obsolete references
}
}
}
真正执行任务
private void mainLoop() {
while (true) //无限执行
try {
TimerTask task;
boolean taskFired;
synchronized(queue) {//线程安全的
// Wait for queue to become non-empty
while (queue.isEmpty() && newTasksMayBeScheduled)
queue.wait();//如果新建的,就等待schedule()
if (queue.isEmpty())
break; // Queue is empty and will forever remain; die
// Queue nonempty; look at first evt and do the right thing
long currentTime, executionTime;
task = queue.getMin();//获取第一个任务
synchronized(task.lock) {
if (task.state == TimerTask.CANCELLED) {
queue.removeMin();//如果是取消的任务,执行下一个
continue; // No action required, poll queue again
}
currentTime = System.currentTimeMillis();
executionTime = task.nextExecutionTime;
if (taskFired = (executionTime<=currentTime)) {//如果超过执行时间
if (task.period == 0) { // Non-repeating, remove
queue.removeMin();//超过时间,却不是重复任务,就设为执行过了
task.state = TimerTask.EXECUTED;
} else { // Repeating task, reschedule
queue.rescheduleMin(//否则设置下一次运行的时间
task.period<0 ? currentTime - task.period
: executionTime + task.period);
}
}
}
if (!taskFired) // Task hasn't yet fired; wait
queue.wait(executionTime - currentTime);//还有任务,就等待该任务
}
if (taskFired) // Task fired; run it, holding no locks
task.run();
} catch(InterruptedException e) {
}
}
}
整个执行过程
首先创建Timer
- 1.构造器
public Timer() {
this("Timer-" + serialNumber());
}
public Timer(boolean isDaemon) {
this("Timer-" + serialNumber(), isDaemon);
}
public Timer(String name) {
thread.setName(name);
thread.start();//会启动线程,但是由于此时queue是空的,thread会进入wait状态
}
- 1.1 TimerThread当中的run方法执行
thread启动之后会调用run方法
public void run() {
try {
mainLoop();
}
接着mainLoop方法, while (queue.isEmpty() && newTasksMayBeScheduled) 刚开始创建,就在此处停止等待。
while (true) //无限执行
try {
TimerTask task;
boolean taskFired;
synchronized(queue) {//线程安全的,每次只允许单个线程访问
// Wait for queue to become non-empty
while (queue.isEmpty() && newTasksMayBeScheduled)
queue.wait();
if (queue.isEmpty())
break; // Queue is empty and will forever remain; die
-
- 调用schedule 方法,会往queue当中添加任务
在这里插入代码片
- 调用schedule 方法,会往queue当中添加任务
public void schedule(TimerTask task, long delay) {
if (delay < 0)
throw new IllegalArgumentException("Negative delay.");
sched(task, System.currentTimeMillis()+delay, 0);
}
private void sched(TimerTask task, long time, long period) {
if (Math.abs(period) > (Long.MAX_VALUE >> 1))
period >>= 1;
synchronized(queue) {
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();
}
}
- 2.1 唤醒线程继续执行
queue.wait();//刚刚卡在这
if (queue.isEmpty())
break; // Queue is empty and will forever remain; die
// Queue nonempty; look at first evt and do the right thing
long currentTime, executionTime;
task = queue.getMin();//获取第一个任务
synchronized(task.lock) {
if (task.state == TimerTask.CANCELLED) {
queue.removeMin();//如果是取消的任务,执行下一个
continue; // No action required, poll queue again
}
currentTime = System.currentTimeMillis();
executionTime = task.nextExecutionTime;
if (taskFired = (executionTime<=currentTime)) {//如果超过执行时间
if (task.period == 0) { // Non-repeating, remove
queue.removeMin();//超过时间,却不是重复任务,就设为执行过了
task.state = TimerTask.EXECUTED;
} else { // Repeating task, reschedule
queue.rescheduleMin(//否则设置下一次运行的时间
task.period<0 ? currentTime - task.period
: executionTime + task.period);
}
}
}
if (!taskFired) // Task hasn't yet fired; wait
queue.wait(executionTime - currentTime);//还有任务,就等待该任务
}
if (taskFired) // Task fired; run it, holding no locks
task.run();
} catch(InterruptedException e) {
}
}
}