jdk中的Timer类理解和学习

1.背景: 最近新出了一个需求,"根据用户输入的时间,进行任务的调度执行"

2.由于之前只是使用一些调度的框架,没有时间研究实现原理,今天就想着看看,定时的底层原理实现过程,方便日后的业务开发

3.首先,不打算直接看源码进行说明.直接说下定时中使用的几个原理点Timer进行说明

①定时任务中只有一个线程和一个任务队列(该队列是一个优先级队列,基于最小堆实现,时间距现在最近的任务排在开头)

②任务的执行是根据当前时间进行判断是否执行,如果任务的执行时间大于当前时间就在队列上等待,否则更新任务的下次时间给任务,然后进行任务的执行

③只要线程启动后,就会在一个while循环中不断的执行任务

4.下面附上源码(源码很简单的),请大家根据上面的解析,进行查看就好理解啦

注意:下面只是Timer中的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) {
                    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;  // No action required, poll queue again
                        }
                        //获取当前时间和下次任务执行时间
                        currentTime = System.currentTimeMillis();
                        executionTime = task.nextExecutionTime;
                        //判断任务执行时间是否小于当前时间,表示小于,就说明可以执行了
                        if (taskFired = (executionTime<=currentTime)) {
                            //如果任务的执行周期是0,说明只要执行一次就好了,就从队列中移除它,这样下一次就不会获取到该任务了
                            if (task.period == 0) {
                                queue.removeMin();
                                task.state = TimerTask.EXECUTED;
                            } else { 
                                //重新设置该任务下一次的执行时间
                                //如果之前设置的period小于0,就用当前时间-period,等于就是当前时间加上周期值
                                //这里的下次执行时间就是当前的执行时间加上周期值
                                //这里涉及到是否以固定频率调用任务的问题,下面再详细讲解
                                queue.rescheduleMin(
                                  task.period<0 ? currentTime   - task.period
                                                : executionTime + task.period);
                            }
                        }
                    }
                    //如果任务的执行时间还没到,就计算出还有多久才到达执行时间,然后线程进入休眠
                    if (!taskFired) 
                        queue.wait(executionTime - currentTime);
                }
                //如果任务的执行时间到了,就执行这个任务
                if (taskFired)
                    task.run();
            } catch(InterruptedException e) {
            }
        }
}

 

5.看完Timer的大致执行过程后,再简单说下ScheduledThreadPoolExecutor这个类

这个类中和Timer不同点是使用了线程池技术,多个线程来执行队列中的任务,其他的原理和Timer是类似的,希望日后看一些技术可以举一反三!!! 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值