Timer定时器

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

    1. 调用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) {
            }
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值