时间轮(Time Wheel)是一种常用的定时器实现方式,它可以用于在指定时间后执行某个任务。时间轮通常由多个槽(Slot)组成,每个槽代表一个时间间隔,例如1秒、2秒、4秒等。每个槽中存储了需要在该时间间隔内执行的任务列表。时间轮会不断地转动,每次转动一个槽的时间间隔,当槽中有任务时,就会执行这些任务。
下面是一个Java代码示例,演示了如何使用时间轮实现定时器功能:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class TimeWheel {
private int tickMs; // 时间轮每个槽的时间间隔,单位毫秒
private int wheelSize; // 时间轮的槽数量
private int currentTickIndex = 0; // 当前时间轮的指针位置
private List<Task>[] wheel; // 时间轮的槽,每个槽存储需要在该时间间隔内执行的任务列表
private ScheduledExecutorService executorService; // 定时任务执行器
public TimeWheel(int tickMs, int wheelSize) {
this.tickMs = tickMs;
this.wheelSize = wheelSize;
this.wheel = new ArrayList[wheelSize];
for (int i = 0; i < wheelSize; i++) {
wheel[i] = new ArrayList<>();
}
this.executorService = Executors.newSingleThreadScheduledExecutor();
}
public void start() {
executorService.scheduleAtFixedRate(() -> {
List<Task> tasks = wheel[currentTickIndex];
for (Task task : tasks) {
task.run();
}
wheel[currentTickIndex].clear();
currentTickIndex = (currentTickIndex + 1) % wheelSize;
}, tickMs, tickMs, TimeUnit.MILLISECONDS);
}
public void addTask(Task task, long delayMs) {
int ticks = (int) (delayMs / tickMs);
int index = (currentTickIndex + ticks) % wheelSize;
wheel[index].add(task);
}
public static void main(String[] args) {
TimeWheel timeWheel = new TimeWheel(1000, 10);
timeWheel.start();
timeWheel.addTask(new Task("task1"), 5000);
timeWheel.addTask(new Task("task2"), 10000);
timeWheel.addTask(new Task("task3"), 15000);
}
static class Task implements Runnable {
private String name;
public Task(String name) {
this.name = name;
}
@Override
public void run() {
System.out.println("Task " + name + " executed at " + System.currentTimeMillis());
}
}
}
在上面的示例中,我们创建了一个时间轮,每个槽的时间间隔为1秒,总共有10个槽。我们使用ScheduledExecutorService来定时执行时间轮的转动,每次转动一个槽的时间间隔。我们还定义了一个Task类,用于表示需要执行的任务。在main方法中,我们向时间轮中添加了3个任务,分别在5秒、10秒和15秒后执行。当时间轮转动到相应的槽时,就会执行相应的任务。
时间轮可以应用于很多场景,其中一些常见的应用场景包括:
1. 定时任务调度:时间轮可以用于实现定时任务调度,例如在指定时间后执行某个任务。
2. 过期缓存清理:时间轮可以用于实现过期缓存的清理,例如将缓存对象放入时间轮中,当时间轮转动到相应的槽时,就可以将过期的缓存对象清理掉。
3. 网络超时检测:时间轮可以用于实现网络超时检测,例如将每个网络请求放入时间轮中,当时间轮转动到相应的槽时,就可以检测是否有请求超时。
4. 负载均衡:时间轮可以用于实现负载均衡,例如将每个请求放入时间轮中,当时间轮转动到相应的槽时,就可以将请求分配给相应的服务器。
没有回复内容