• java.util.Timer浅析


       Timer是JDK中的定时调度类,主要用来定时触发任务:

    1. 用法:

    Timer是调度控制器,TimerTask是可调度的任务:

       1: import java.util.Date;
       2: import java.util.TimerTask;
       3:  
       4: public class PlainTimerTask extends TimerTask {
       5:  
       6:     @Override
       7:     public void run() {
       8:         System.out.println(new Date());
       9:  
      10:     }
      11:  
      12: }
      13:  

    调度过程:

       1: import java.util.Timer;
       2:  
       3: public class TimerRunner {
       4:     
       5:     public static void main(String [] args){
       6:         Timer timer=new Timer();
       7:         timer.schedule(new PlainTimerTask(), 5000L);
       8:     }
       9:  
      10: }

    2.原理:

         其基本处理模型是单线程调度的任务队列模型,Timer不停地接受调度任务,所有任务接受Timer调度后加入TaskQueue,TimerThread不停地去TaskQueue中取任务来执行.

    Timer

         从图上不难看出,这就是生产者--消费者模型的一种特例:多生产者,单消费者模型。

         此种消息队列实现方式在浏览器中的编程模型中也有类似的实现,javascript中的定时执行函数setTimeout(expression,milliseconds)也是基于此种原理实现的。

         此种方式的不足之处为当某个任务执行时间较长,以致于超过了TaskQueue中下一个任务开始执行的时间,会影响整个任务执行的实时性。为了提高实时性,可以采用多个消费者一起消费来提高处理效率,避免此类问题的实现。

    3.核心代码:

       1: private void mainLoop() {
       2:         while (true) {
       3:             try {
       4:                 TimerTask task;
       5:                 boolean taskFired;
       6:                 synchronized(queue) {
       7:                     // Wait for queue to become non-empty
       8:                     while (queue.isEmpty() && newTasksMayBeScheduled)
       9:                         queue.wait();
      10:                     if (queue.isEmpty())
      11:                         break; // Queue is empty and will forever remain; die
      12:  
      13:                     // Queue nonempty; look at first evt and do the right thing
      14:                     long currentTime, executionTime;
      15:                     task = queue.getMin();
      16:                     synchronized(task.lock) {
      17:                         if (task.state == TimerTask.CANCELLED) {
      18:                             queue.removeMin();
      19:                             continue;  // No action required, poll queue again
      20:                         }
      21:                         currentTime = System.currentTimeMillis();
      22:                         executionTime = task.nextExecutionTime;
      23:                         if (taskFired = (executionTime<=currentTime)) {
      24:                             if (task.period == 0) { // Non-repeating, remove
      25:                                 queue.removeMin();
      26:                                 task.state = TimerTask.EXECUTED;
      27:                             } else { // Repeating task, reschedule
      28:                                 queue.rescheduleMin(
      29:                                   task.period<0 ? currentTime   - task.period
      30:                                                 : executionTime + task.period);
      31:                             }
      32:                         }
      33:                     }
      34:                     if (!taskFired) // Task hasn't yet fired; wait
      35:                         queue.wait(executionTime - currentTime);
      36:                 }
      37:                 if (taskFired)  // Task fired; run it, holding no locks
      38:                     task.run();
      39:             } catch(InterruptedException e) {
      40:             }
      41:         }
      42:     }

    1.先获得队列锁,然后去TaskQueue中取TimerTask,然后去判断此队列为空且新任务可安排标记是打开的。如果不满足,线程等待,将队列锁释放。

    2.如果队列为空,那么跳出死循环。

    3.取得队列中的下一个元素,并获得任务锁。

    4.检查任务状态,如果任务状态为取消,那么直接取消,并跳过此轮循环。

    5.得到任务的计划执行时间,并检查与当前时间的先后,如果当前时间已经到或者超过计划执行时间,那么置状态位为执行。

    6.释放任务锁。

    7.如果没有,线程等待执行时间和当前时间差。

    8.释放队列锁

    9.看任务是否可以执行标记,来确定是否执行任务

    10反复从1开始

  • 相关阅读:
    Homekit_Dohome_智能灯带
    智能蓝牙球泡灯
    域名与网站名区别
    手机屏幕的分辨率和图像尺寸关系
    关于背景图片定位问题
    http://selectorgadget.com/
    经典网址
    进度条
    html5 触摸控制
    html背景音乐
  • 原文地址:https://www.cnblogs.com/jinspire/p/2345256.html
Copyright © 2020-2023  润新知