定时任务----时间轮算法

定时任务----时间轮算法

背景

在实际的业务场景中,我们常常需要周期性执行一些任务,比如巡查系统资源,处理过期数据等等。这些事情如果人工去执行的话,无疑是对人力资源的浪费。因此我们就开发出了定时任务。目前业界已有许多出色的定时任务框架,如quartz,elastic-job,包括SpringBoot也提供了定时任务,当然JDK本身也提供了定时任务功能。
那么我们在用这些框架的时候,有没有想过它们是怎么实现定时任务的呢?时间轮算法就是这样一种实现定时任务的方法。

概述

时间轮算法是通过一个时间轮去维护定时任务,按照一定的时间单位对时间轮进行划分刻度。然后根据任务的延时计算任务该落在时间轮的第几个刻度,如果任务时长超出了时间轮的刻度数量,则增加一个参数记录时间轮需要转动的圈数。
时间轮每转动一次就检查当前刻度下的任务圈数是否为0,如果为0说明时间到了就执行任务,否则就减少任务的圈数。这样看起来已经很好了,可以满足基本的定时任务需求了,但是我们还能不能继续优化一下呢?答案是可以的。想想我们家里的水表,它是不是有多个轮子在转动,时间轮是不是也可以改造成多级联动呢?建立3个时间轮,月轮、周轮、日轮,月轮存储每个月份需要执行定时任务,转动时将当月份的任务抛到周轮,周轮转动时将当天的任务抛到日轮中,日轮转动时直接执行当前刻度下的定时任务。

研究分析

笔者从github找了一个时间轮的项目,我们来研究一下时间轮的具体实现是怎样的。

https://github.com/ifesdjeen/hashed-wheel-timer.git

clone下来的项目目录是这样的,我们只需要查看core模块下的几个类就ok了。
在这里插入图片描述
HashedWheelTimer类就是实现时间轮的类,由于篇幅有限,下面只选取一些重要代码片段讲解

时间轮属性
public class HashedWheelTimer implements ScheduledExecutorService {
   
 //时间轮默认转动一次的时间,10毫秒
  public static final  long   DEFAULT_RESOLUTION = TimeUnit.NANOSECONDS.convert(10, TimeUnit.MILLISECONDS);
  //时间轮默认尺寸
  public static final  int    DEFAULT_WHEEL_SIZE = 512;
  private static final String DEFAULT_TIMER_NAME = "hashed-wheel-timer";

  //时间轮
  private final Set<Registration<?>>[] wheel;
  //时间轮尺寸
  private final int                    wheelSize;
  //转动一次花费的时间
  private final long                   resolution;
  //运转时间轮线程的执行器
  private final ExecutorService        loop;
  //运转定时任务的执行器
  private final ExecutorService        executor;
  //时间轮转动的等待策略
  private final WaitStrategy           waitStrategy;
  //当前时间轮所在的刻度
  private volatile int cursor = 0;
构造时间轮
 public HashedWheelTimer(String name, long res, int wheelSize, WaitStrategy strategy, ExecutorService exec) {
   
    this.waitStrategy = strategy;

    this.wheel = new Set[wheelSize];
    for (int i = 0; i < wheelSize; i++) {
   
      wheel[i] = new ConcurrentSkipListSet<>();
    }

    this.wheelSize = wheelSize;

    this.resolution = res;
    final Runnable loopRunnable = new Runnable() {
   
      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值