public class TimeHashWheel {
// 任务存储
private Map<Integer, List<Task>> taskMap;
// 每轮时长
private int duration;
// 单期耗时
private int tick;
private volatile boolean start;
public static void main(String[] args) {
TimeHashWheel wheel = new TimeHashWheel(6000, 100);
wheel.start();
for (int i = 0; i < 100; i++) {
String date = "task_no_" + i;
int delay = (int) (Math.random() * 3 * 6000);
wheel.addTask(date, delay);
System.out.println("insert task : " + date + ", delay by : " + delay);
}
}
public TimeHashWheel(int duration, int tick) {
this.taskMap = new HashMap<>(duration / tick);
this.duration = duration;
this.tick = tick;
this.start = true;
}
public void addTask(String data, int delay) {
int bucket = (delay % duration) / tick;
int round = delay / duration;
taskMap.computeIfAbsent(bucket, k -> new ArrayList<>());
taskMap.get(bucket).add(new Task(data, round));
}
public void start() {
Executors.newSingleThreadExecutor().execute(() -> {
try {
int begin = 0;
while (start) {
if ((begin == (duration / tick))) {
System.out.println("tick to next round ---- ");
begin = 0;
}
System.out.println("tick to :" + (begin));
List<Task> list = taskMap.get(begin++);
System.out.println("found bucket has " + (list == null ? 0 : list.size())
+ " task");
if (!CollectionUtils.isEmpty(list)) {
Iterator<Task> it = list.iterator();
while (it.hasNext()) {
Task task = it.next();
if (task.round > 0) {
task.round--;
} else {
System.out.println("============= execute task : " + task.data);
it.remove();
}
}
}
TimeUnit.MILLISECONDS.sleep(tick);
}
} catch (Exception e) {
e.printStackTrace();
}
});
}
class Task {
private String data;
private int round;
public Task(String data, int round) {
this.data = data;
this.round = round;
}
}
}