Timer源码分析

public class Timer {
    /**
     * 定时器队列
     */
    private final TaskQueue queue = new TaskQueue();
    /**
     * 定时器线程
     */
    private final TimerThread thread = new TimerThread(queue);
    /**
     * 起名专用
     */
    private final static AtomicInteger nextSerialNumber = new AtomicInteger(0);

    private static int serialNumber() {
        return nextSerialNumber.getAndIncrement();
    }

    public Timer() {
        this("Timer-" + serialNumber());
    }

    public Timer(boolean isDaemon) {
        this("Timer-" + serialNumber(), isDaemon);
    }

    public Timer(String name) {
        thread.setName(name);
        thread.start();
    }

    public Timer(String name, boolean isDaemon) {
        thread.setName(name);
        thread.setDaemon(isDaemon);
        thread.start();
    }

    public void schedule(TimerTask task, long delay) {
        if (delay < 0) throw new IllegalArgumentException("Negative delay.");
        sched(task, System.currentTimeMillis() + delay, 0);
    }

    public void schedule(TimerTask task, Date time) {
        sched(task, time.getTime(), 0);
    }

    public void schedule(TimerTask task, long delay, long period) {
        /**
         * 参数判断
         */
        if (delay < 0)
            throw new IllegalArgumentException("Negative delay.");
        if (period <= 0)
            throw new IllegalArgumentException("Non-positive period.");
        sched(task, System.currentTimeMillis() + delay, -period);
    }

    public void schedule(TimerTask task, Date firstTime, long period) {
        if (period <= 0)
            throw new IllegalArgumentException("Non-positive period.");
        sched(task, firstTime.getTime(), -period);
    }

    public void scheduleAtFixedRate(TimerTask task, long delay, long period) {
        if (delay < 0)
            throw new IllegalArgumentException("Negative delay.");
        if (period <= 0)
            throw new IllegalArgumentException("Non-positive period.");
        sched(task, System.currentTimeMillis() + delay, period);
    }

    public void scheduleAtFixedRate(TimerTask task, Date firstTime,
                                    long period) {
        if (period <= 0) throw new IllegalArgumentException("Non-positive period.");
        sched(task, firstTime.getTime(), period);
    }

    /**
     * 添加任务到计时队列
     *
     * @param task   任务item
     * @param time   执行时间
     * @param period 间隔
     */
    private void sched(TimerTask task, long time, long period) {
        if (time < 0) throw new IllegalArgumentException("Illegal execution time.");
        /**
         * 比long最大值的1/2还大?减半
         */
        if (Math.abs(period) > (Long.MAX_VALUE >> 1)) period >>= 1;
        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);
            /**
             * 如果是否个,通知来任务了,因为只有当queue为空才会卡主
             */
            if (queue.getMin() == task) queue.notify();
        }
    }

    /**
     * 取消执行,请队列中的任务清空
     */
    public void cancel() {
        synchronized (queue) {
            thread.newTasksMayBeScheduled = false;
            queue.clear();
            queue.notify();
        }
    }

    /**
     * 移除所以为取消状态的任务
     *
     * @return
     */
    public int purge() {
        int result = 0;
        synchronized (queue) {
            for (int i = queue.size(); i > 0; i--) {
                if (queue.get(i).state == TimerTask.CANCELLED) {
                    queue.quickRemove(i);
                    result++;
                }
            }
            if (result != 0)
                queue.heapify();
        }
        return result;
    }
}
class TimerThread extends Thread {

    boolean newTasksMayBeScheduled = true;    // 是否取消
    private TaskQueue queue;

    TimerThread(TaskQueue queue) {
        this.queue = queue;
    }

    public void run() {
        try {
            mainLoop();
        } finally {
            synchronized (queue) {
                newTasksMayBeScheduled = false;
                queue.clear();
            }
        }
    }

    private void mainLoop() {
        while (true) {
            try {
                TimerTask task;
                boolean taskFired;
                synchronized (queue) {
                    while (queue.isEmpty() && newTasksMayBeScheduled) queue.wait();
                    if (queue.isEmpty()) break;
                    long currentTime, executionTime;
                    task = queue.getMin();
                    synchronized (task.lock) {
                        if (task.state == TimerTask.CANCELLED) {
                            queue.removeMin();
                            continue;
                        }
                        currentTime = System.currentTimeMillis();  // 当前时间
                        executionTime = task.nextExecutionTime;  //  任务执行时间
                        if (taskFired = (executionTime <= currentTime)) {
                            // 不重复执行
                            if (task.period == 0) {
                                queue.removeMin();
                                task.state = TimerTask.EXECUTED;
                            } else {
                                queue.rescheduleMin(task.period < 0 ? currentTime - task.period : executionTime + task.period);
                            }
                        }
                    }
                    if (!taskFired) queue.wait(executionTime - currentTime);
                }
                if (taskFired)
                    task.run();
            } catch (InterruptedException e) {
            }
        }
    }
}
class TaskQueue {
    private TimerTask[] queue = new TimerTask[128];  // 任务数组
    private int size = 0;

    int size() {
        return size;
    }

    /**
     * 添加任务
     *
     * @param task
     */
    void add(TimerTask task) {
        if (size + 1 == queue.length)
            queue = Arrays.copyOf(queue, 2 * queue.length);
        queue[++size] = task;
        // 这块用向上调整,应该是因为新加的任务在最后面吧
        fixUp(size);
    }

    /**
     * 获取时间最小的任务
     *
     * @return
     */
    TimerTask getMin() {
        return queue[1];
    }

    TimerTask get(int i) {
        return queue[i];
    }

    void removeMin() {
        queue[1] = queue[size];
        queue[size--] = null;
        fixDown(1);
    }

    /**
     * 移除任务
     *
     * @param i
     */
    void quickRemove(int i) {
        assert i <= size;
        queue[i] = queue[size];
        queue[size--] = null;
    }

    /**
     * 重复执行,重新排序
     *
     * @param newTime
     */
    void rescheduleMin(long newTime) {
        queue[1].nextExecutionTime = newTime;
        fixDown(1);
    }

    /**
     * 判空
     *
     * @return
     */
    boolean isEmpty() {
        return size == 0;
    }

    /**
     * 清楚数组
     */
    void clear() {
        for (int i = 1; i <= size; i++)
            queue[i] = null;
        size = 0;
    }

    /**
     * 向上调整 复杂度: O (nlgn)
     *
     * @param k
     */
    private void fixUp(int k) {
        while (k > 1) {
            int j = k >> 1;
            if (queue[j].nextExecutionTime <= queue[k].nextExecutionTime)
                break;
            TimerTask tmp = queue[j];
            queue[j] = queue[k];
            queue[k] = tmp;
            k = j;
        }
    }

    /**
     * 向下调整
     *
     * @param k
     */
    private void fixDown(int k) {
        int j;
        while ((j = k << 1) <= size && j > 0) {
            if (j < size &&
                    queue[j].nextExecutionTime > queue[j + 1].nextExecutionTime)
                j++;
            if (queue[k].nextExecutionTime <= queue[j].nextExecutionTime)
                break;
            TimerTask tmp = queue[j];
            queue[j] = queue[k];
            queue[k] = tmp;
            k = j;
        }
    }

    void heapify() {
        for (int i = size / 2; i >= 1; i--)
            fixDown(i);
    }
}
public abstract class TimerTask implements Runnable {
    final Object lock = new Object();
    int state = VIRGIN;
    static final int VIRGIN = 0;     // 初始
    static final int SCHEDULED = 1;  // 预约
    static final int EXECUTED = 2;   // 已执行
    static final int CANCELLED = 3;  // 已取消
    long nextExecutionTime;
    long period = 0;

    protected TimerTask() {
    }

    public abstract void run();

    /**
     * 设置状态为取消
     *
     * @return
     */
    public boolean cancel() {
        synchronized (lock) {
            boolean result = (state == SCHEDULED);
            state = CANCELLED;
            return result;
        }
    }

    public long scheduledExecutionTime() {
        synchronized (lock) {
            return (period < 0 ? nextExecutionTime + period
                    : nextExecutionTime - period);
        }
    }
}

 

转载于:https://my.oschina.net/u/3342652/blog/1581199

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值