All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.hutool.cron.timingwheel.TimingWheel Maven / Gradle / Ivy

There is a newer version: 5.8.33
Show newest version
package cn.hutool.cron.timingwheel;

import cn.hutool.log.StaticLog;

import java.util.function.Consumer;

/**
 * 多层时间轮,常用于延时任务。
* 时间轮是一种环形数据结构,由多个槽组成,每个槽中存放任务集合。
* 一个单独的线程推进时间一槽一槽的移动,并执行槽中的任务。 * * @author eliasyaoyc, looly */ public class TimingWheel { /** * 一个时间槽的范围 */ private final long tickMs; /** * 时间轮大小,时间轮中时间槽的个数 */ private final int wheelSize; /** * 时间跨度,当前时间轮总间隔,即单个槽的跨度*槽个数 */ private final long interval; /** * 时间槽 */ private final TimerTaskList[] timerTaskLists; /** * 当前时间,指向当前操作的时间格,代表当前时间 */ private long currentTime; /** * 上层时间轮 */ private volatile TimingWheel overflowWheel; /** * 任务处理器 */ private final Consumer consumer; /** * 构造 * * @param tickMs 一个时间槽的范围,单位毫秒 * @param wheelSize 时间轮大小 * @param consumer 任务处理器 */ public TimingWheel(long tickMs, int wheelSize, Consumer consumer) { this(tickMs, wheelSize, System.currentTimeMillis(), consumer); } /** * 构造 * * @param tickMs 一个时间槽的范围,单位毫秒 * @param wheelSize 时间轮大小 * @param currentTime 当前时间 * @param consumer 任务处理器 */ public TimingWheel(long tickMs, int wheelSize, long currentTime, Consumer consumer) { this.tickMs = tickMs; this.wheelSize = wheelSize; this.interval = tickMs * wheelSize; this.timerTaskLists = new TimerTaskList[wheelSize]; initTimerTaskList(); //currentTime为tickMs的整数倍 这里做取整操作 this.currentTime = currentTime - (currentTime % tickMs); this.consumer = consumer; } /** * 添加任务到时间轮 * * @param timerTask 任务 * @return 是否成功 */ public boolean addTask(TimerTask timerTask) { long expiration = timerTask.getDelayMs(); //过期任务直接执行 if (expiration < currentTime + tickMs) { return false; } else if (expiration < currentTime + interval) { //当前时间轮可以容纳该任务 加入时间槽 long virtualId = expiration / tickMs; int index = (int) (virtualId % wheelSize); StaticLog.debug("tickMs: {} ------index: {} ------expiration: {}", tickMs, index, expiration); TimerTaskList timerTaskList = timerTaskLists[index]; timerTaskList.addTask(timerTask); if (timerTaskList.setExpiration(virtualId * tickMs)) { //添加到delayQueue中 consumer.accept(timerTaskList); } } else { //放到上一层的时间轮 TimingWheel timeWheel = getOverflowWheel(); timeWheel.addTask(timerTask); } return true; } /** * 推进时间 * * @param timestamp 推进的时间 */ public void advanceClock(long timestamp) { if (timestamp >= currentTime + tickMs) { currentTime = timestamp - (timestamp % tickMs); if (overflowWheel != null) { //推进上层时间轮时间 this.getOverflowWheel().advanceClock(timestamp); } } } /** * 创建或者获取上层时间轮 */ private TimingWheel getOverflowWheel() { if (overflowWheel == null) { synchronized (this) { if (overflowWheel == null) { overflowWheel = new TimingWheel(interval, wheelSize, currentTime, consumer); } } } return overflowWheel; } /** * 初始 timerTaskLists */ private void initTimerTaskList() { for (int i = 0; i < this.timerTaskLists.length; i++) { this.timerTaskLists[i] = new TimerTaskList(); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy