zoukankan      html  css  js  c++  java
  • java单线程定时器任务学习笔记

    单线程模式(由 Timer和TimerTask 协同实现)

      使用util包下面的Timer工具,简单看一下Timer类的组成。

      

      queue: TaskQueque,本质是一个 TimerTask数组,初始化大小为 128

      thread:TImerThread ,本质就是一个线程,Timer单线程定时任务的执行线程

      ....  , 其他以后再看

      其中,Timer中有六个方法

      

      两个参数的方法,一个是设置任务开始延迟时间,一个是设置任务开始的时间。都是一次性任务。

      有三个参数的方法比两个参数的方法多个long类型的间隔时间参数。其中能定时执行的原理是 , mianLoop()里面是个死循环

      

        下面讲一下这两个方法的差别

      

        

        再仔细分析 , 下面这段代码的流程,在详细分析一下

                  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
    
                        // Queue nonempty; look at first evt and do the right thing
                        long currentTime, executionTime;
                        task = queue.getMin();
                        synchronized(task.lock) {
                  // 当前任务为取消状态,就从queque中去除当前任务
    if (task.state == TimerTask.CANCELLED) {
                    // 去除第一个元素 queue.removeMin();
    continue; // No action required, poll queue again } currentTime = System.currentTimeMillis(); executionTime = task.nextExecutionTime;
                    //当 当前时间>=应该执行的时间, 任务就激活
    if (taskFired = (executionTime<=currentTime)) {
                    // 如果period == 0说明是一次性任务,从queque去除(执行在下面,不要担心不会执行,这里先去除)
    if (task.period == 0) { // Non-repeating, remove queue.removeMin(); task.state = TimerTask.EXECUTED; } else { // Repeating task, reschedule

                       // 重新设置task的nextExecutionTime,schedule传进来的是负数, schuduleAtFixedRate是正数 , 设置完后还会根据 nextExecutionTime进行排序 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();

      

    其中 rescheduleMin 中的排序逻辑如下



    由此可见,会在queue里面选出一个下次执行时间最小的task放到队首

    执行结果借鉴如下


    其中 task1是schedule执行的 , nextExecutionTime = currentTime + period
    其中 task是scheduleAtFixedRate执行的  ,  nextExecutionTime = executionTime(上一个) + period

    可见,除了新添加task放到队首外,其余每次都是选最早的那个任务开始执行


      

  • 相关阅读:
    Event 事件(最简单实用)
    Codeforces Beta Round #93_A题
    欧几里得算法扩展(extended gcd)解不定方程_初入门
    HDU2955_Robberies_01背包变种
    HDU2602_Bone Collector_很水的01背包
    USACO_2_1_3_Sorting a ThreeValued Sequence_交换环
    Codeforces Beta Round #93_B题
    中国剩余定理的_非互素同余模板
    HDU1114_DP_完全背包
    HDU3809_Decrypt coordinate_迭代法
  • 原文地址:https://www.cnblogs.com/liujiaa/p/8082045.html
Copyright © 2011-2022 走看看