package com.rural_vibration.common.utils;import java.util.Date;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;public class TimeWheelTest {// 时间轮大小,每一格代表1秒private final int WHEEL_SIZE = 60;// 时间轮的每一格,用来存储定时任务private TimeSlot[] timeSlots;// 当前指针指向的时间槽private int currentSlotIndex = 0;// 下一级时间轮private TimeWheelTest nextLevelWheel;// 延迟队列,用来存储需要延迟执行的任务private DelayQueue<Task> delayQueue = new DelayQueue<>();public TimeWheelTest() {this.timeSlots = new TimeSlot[WHEEL_SIZE];for (int i = 0; i < WHEEL_SIZE; i++) {this.timeSlots[i] = new TimeSlot();}}// 添加任务public void addTask(Task task) {long delay = task.getDelay(TimeUnit.SECONDS);if (delay < WHEEL_SIZE) {// 在当前时间轮的对应时间槽中添加任务int index = (currentSlotIndex + (int) delay) % WHEEL_SIZE;timeSlots[index].addTask(task);} else {// 在下一级时间轮中添加任务if (nextLevelWheel == null) {synchronized (this) {if (nextLevelWheel == null) {nextLevelWheel = new TimeWheelTest();}}}nextLevelWheel.addTask(task);}}// 执行任务public void run() {// 获取延迟队列中已经到期的任务Task task = delayQueue.poll();while (task != null) {addTask(task);task = delayQueue.poll();}// 执行当前时间槽中的任务timeSlots[currentSlotIndex].run();// 指针向前移动一格currentSlotIndex = (currentSlotIndex + 1) % WHEEL_SIZE;// 如果有下一级时间轮,则执行下一级时间轮的任务if (nextLevelWheel != null) {nextLevelWheel.run();}}// 时间轮中的时间槽,用来存储任务private class TimeSlot {private TaskList taskList = new TaskList();public void addTask(Task task) {taskList.addTask(task);}public void run() {taskList.run();}}// 任务链表private class TaskList {private TaskNode head;private TaskNode tail;public void addTask(Task task) {TaskNode node = new TaskNode(task);if (head == null) {head = tail = node;} else {tail.next = node;tail = node;}}public void run() {TaskNode node = head;while (node != null) {node.task.run();node = node.next;}}}// 任务节点private static class TaskNode {private Task task;private TaskNode next;public TaskNode(Task task) {this.task = task;}}// 任务类,实现Delayed接口private static class Task implements Delayed {private long startTime; // 任务开始时间private Runnable runnable; // 任务执行的内容public Task(long delay, Runnable runnable) {this.startTime = System.currentTimeMillis() + delay * 1000;this.runnable = runnable;}@Overridepublic long getDelay(TimeUnit unit) {long delay = startTime - System.currentTimeMillis();return unit.convert(delay, TimeUnit.MILLISECONDS);}@Overridepublic int compareTo(Delayed o) {long delay = getDelay(TimeUnit.MILLISECONDS) - o.getDelay(TimeUnit.MILLISECONDS);if (delay < 0) {return -1;} else if (delay > 0) {return 1;} else {return 0;}}public void run() {runnable.run();}}public static void main(String[] args) throws InterruptedException {TimeWheelTest timeWheel = new TimeWheelTest();int time = 0;// 添加10个任务,分别延迟1秒、2秒、3秒、4秒、5秒、6秒、7秒、8秒、9秒和10秒执行for (int i = 1; i <= 10; i++) {final int delay = i;timeWheel.addTask(new Task(delay, () -> System.out.println("Task " + delay + " is executed. now: " + new Date().getTime())));System.out.println("正在添加任务"+ i);}// 每秒钟执行一次时间轮while (true) {timeWheel.run();Thread.sleep(1000);System.out.println("\r\n" + "\t" + "========================================================="+ ++time);if (time >= 60){time=1;}}}
}