定时任务

2022-03-22  本文已影响0人  爱健身的兔子

应用场景


定时任务实现

阶段一

每隔一小时清理日志

main(){
    Thread t = new Thread(()->{
        while(true){
            sleep(一小时);
            清理日志------
        }
    })   

}
阶段二
class Task implements Runnable{
    void run(){
        清理日志;
    }
}
class TimeOut{
    private Date timeout;//执行的日志
}
class Timer extends Thread{
    private Task task;
    private TimeOut timeOut;
    void run(){
     while(true){
        sleep(一分钟);
        if(timeOut到期){
            task.run();    
        }
    }
  }
}
main(){
     for(一堆任务){
        new Timer(task,timeOut).start();
    }
}

定时任务数据结构

class TimeTask implements Comparable<TimeTask>{
    private Long nextExeTime; 
    private Runnable job;
}
单链表
单链表
main(){
    while(true){
        sleep(一分钟){
            for(TimeTask : list){
                if(timeTask不需要执行){
                    list.remove(timetask);
                }
                if(TimeTask是否到期){
                    timetask.run();
                    timetask.nextExeTime = 计算下一个执行时间;
                }
            }
        }
    }
}
小顶堆
小顶堆.jpg
main(){
    while(true){
       TimeTask = heep.peek(); 
       long sleepTime;
       while((sleepTime = timeTask.getNextExeTime - now) > 0 ){
          timeTask.run();
       }
       heep.remove();
       计算下一次 timeTask.nextExeTime
       if(还需要执行){
            heep.add(timeTask);
      }
   }
}
时间轮
  1. 一级时间轮
class TimeOut{
    TimeOut pre;
    TimeOut next;
    TimeTask task;
}
class Bucket{
    TimeOut head;
    TimeOut tail;
}
class WheelTimer{
      Bucket[] buckets;
      TimeUnit timeUnit;
      Long tickDuration;

    main(){
       int tick = 0;
       //不断轮询buckets,类似钟表的滴答
       while(true){
         //休眠一个tick,需要接口timeunit计算。
         sleep(tickTime);
        TimeOut current = bucket[tick];
        while(current.next != null){
            current.run();
            current = current.next;
        }
      }
   }
}
  1. round时间轮
class TimeOut{
    TimeOut pre;
    TimeOut next;
    TimeTask task;
    Integer round;
}

class WheelTimer{
    main(){
       int tick = 0;
       //不断轮询buckets,类似钟表的滴答
       while(true){
         //休眠一个tick,需要接口timeunit计算。
         sleep(tickTime);
        TimeOut current = bucket[tick];
        while(current.next != null){
            current.round--;
            if(current.round<=0){
               current.run();
            }
            current = current.next;
        }
      }
   }
}
  1. 分成时间轮

参考:时间轮算法

上一篇 下一篇

猜你喜欢

热点阅读