环形队列高效触发大量超时任务的算法实现
发表于:2025-12-03 作者:千家信息网编辑
千家信息网最后更新 2025年12月03日,基于环形队列的超时触发算法只需要一个timer即可实现批量超时任务的触发,CPU消耗低,效率高。原理介绍,下面是此算法的简单实现。1,TaskHolder.javapackage com.zws.ti
千家信息网最后更新 2025年12月03日环形队列高效触发大量超时任务的算法实现
基于环形队列的超时触发算法只需要一个timer即可实现批量超时任务的触发,CPU消耗低,效率高。原理介绍,下面是此算法的简单实现。
1,TaskHolder.java
package com.zws.timer;/** * * @author wensh.zhu * @date 2018-04-22 */public class TaskHolder { /** 任务所需等待的圈数,即任务需要走几圈**/ private int cycles; private int delays; private Runnable task; public TaskHolder() {} public TaskHolder(int cycles, int delays, Runnable task) { this.cycles = cycles; this.delays = delays; this.task = task; } public boolean isTimeOut() { return cycles <= 0; } public void cutDown() { cycles --; } public int getCycles() { return cycles; } public void setCycles(int cycles) { this.cycles = cycles; } public int getDelays() { return delays; } public void setDelays(int delays) { this.delays = delays; } public Runnable getTask() { return task; } public void setTask(Runnable task) { this.task = task; } @Override public String toString() { return "TaskHolder[cycles=" + cycles + ", delays=" + delays + "]"; } }2,TimerContext.java
package com.zws.timer;import java.util.Map;import java.util.Queue;import java.util.concurrent.ConcurrentHashMap;import java.util.concurrent.ConcurrentLinkedQueue;/** * * @author wensh.zhu * @date 2018-04-22 */public class TimerContext { public static final int DEFAULT_TICKS = 60; public static final int DEFAULT_TICK_DURATION = 1; private Map> taskHolders; private volatile int currentTick = 0; /** tick一圈的长度 **/ private int ticks = DEFAULT_TICKS; /** 每tick一次的时间间隔,单位:秒**/ private int tickDuration = DEFAULT_TICK_DURATION; public TimerContext() { init(); } public TimerContext(int ticks, int tickDuration) { if (ticks <= 0) throw new IllegalArgumentException("ticks must be greater than 0"); if (tickDuration <= 0) throw new IllegalArgumentException("tickDuration must be greater than 0"); this.ticks = ticks; this.tickDuration = tickDuration; init(); } private void init() { taskHolders = new ConcurrentHashMap>(); for (int i = 0; i < ticks; i ++) taskHolders.put(i, new ConcurrentLinkedQueue()); } /** * 添加一个定时任务并计算需要走的圈数和落脚的index * @param task * @param delays */ public void addTask(Runnable task, int delays) { if (task == null) throw new NullPointerException("task must not be null"); if (delays <=0) throw new IllegalArgumentException("delays must be greater than 0"); int allSeconds = ticks * tickDuration; int cycles = delays / allSeconds; int index = ((delays % allSeconds) / tickDuration) + currentTick; TaskHolder metaData = new TaskHolder(cycles, delays, task); Queue tasks = taskHolders.get(index); synchronized (tasks) { tasks.add(metaData); } } public int tick() { currentTick = (currentTick + 1) % ticks; return currentTick; } public Queue getCurrentTasks() { return taskHolders.get(currentTick); } public int getCurrentTick() { return currentTick; } public int getTicks() { return ticks; } public int getTickDuration() { return tickDuration; } @Override public String toString() { return "TimerContext [timers=" + taskHolders + ", ticks=" + ticks + ", tickDuration=" + tickDuration + ", currentTick=" + currentTick + "]"; }} 3,TimerScheduler.java
package com.zws.timer;import java.io.IOException;import java.util.Iterator;import java.util.Queue;import java.util.Timer;import java.util.TimerTask;/** * 用于判断定时器是否到时、执行任务、维护定时器状态。 * @author wensh.zhu * @date 2018-04-22 */public class TimerScheduler extends TimerTask { private TimerContext timerContext; public TimerScheduler() {} public TimerScheduler(TimerContext timerContext) { this.timerContext = timerContext; } /** * 定时检测,如果定时器触发时间到了就从集合中删除并执行任务,否则圈数减一。 */ @Override public void run() { if (timerContext == null) return; Queue tasks = timerContext.getCurrentTasks(); synchronized (tasks) { Iterator itor = tasks.iterator(); while (itor.hasNext()) { TaskHolder timer = itor.next(); if (timer.isTimeOut()) { itor.remove(); new Thread(timer.getTask()).start(); } else { timer.cutDown(); } } } timerContext.tick(); } public void addTask(Runnable task, int delays) { timerContext.addTask(task, delays); } public TimerContext getTimerContext() { return timerContext; } public void setTimerContext(TimerContext timerContext) { this.timerContext = timerContext; } public static void main(String[] args) throws IOException { TimerContext context = new TimerContext(60, 1); TimerScheduler sheduler = new TimerScheduler(context); sheduler.addTask(new Runnable() { public void run() { System.out.println(DateUtils.now()); } }, 60); System.out.println(DateUtils.now()); Timer timer = new Timer(); timer.scheduleAtFixedRate(sheduler, 0, context.getTickDuration() * 1000L); System.in.read(); } } 4,DateUtils.java
package com.zws.timer;import java.time.LocalDateTime;import java.time.format.DateTimeFormatter;/** * * @author wensh.zhu * @date 2018-04-22 */public class DateUtils { public static final String DEFAULT_PATTERN = "yyyy-MM-dd HH:mm:ss"; public static String now() { LocalDateTime time = LocalDateTime.now(); return time.format(DateTimeFormatter.ofPattern(DEFAULT_PATTERN)); } public static String plusSeconds(int seconds) { LocalDateTime time = LocalDateTime.now(); time.plusSeconds(seconds); return time.format(DateTimeFormatter.ofPattern(DEFAULT_PATTERN)); }}
任务
定时器
算法
时间
环形
队列
到时
单位
原理
效率
状态
长度
务所
检测
消耗
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
公司组建网络技术部方案
全面加强村级网络安全建设通知
互联网 健康科技有限公司
网络安全策略的设计
网络安全拓扑图片大全
投抖加说服务器打瞌睡了
宣传部网络安全做什么
山东云服务器租用云空间
软件开发后台操作
两江新区互联网科技
华为手机服务器系统密码
中国mc服务器地址 手机版
sql数据库需要每天备份吗
剑灵一区哪个服务器好
数据库基础考试只有选择题吗
建立费用发生数据库
公安局 数据库
打服务器ip
福建lol服务器云空间
oracle数据库登录账号密码
校园网络专用服务器设备
饥荒服务器刷新率60
陕西省安康市有软件开发公司吗
c 连接数据库之后跳转页面
梦诛服务器搭建
黄岩网络技术公司
服务器激活苹果
消息推送服务器
株洲游戏软件开发排名
网络安全的扩展知识讨论