时间轮算法

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;}}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/627350.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

安卓四大组件

安卓四大组件分别是&#xff1a;活动&#xff08;Activity&#xff09;、服务&#xff08;Service&#xff09;、广播接收器&#xff08;Broadcast Receiver&#xff09;和内容提供器&#xff08;Content Provider&#xff09;。下面我们将对这四大组件进行详细的介绍。 一、活…

【个人笔记】由浅入深分析 ClickHouse

项目中不少地方使用到ClickHouse,就对它做了一个相对深入一点的了解和研究。并对各种知识点及整理过程中的一些理解心得进行了汇总并分享出来,希望对其他同学能有帮助。 本文主要讲解ClickHouse的特点、读写过程、存储形式、索引、引擎、物化视图等特性。 适合 入门和进阶 大…

bvh格式转换

目录 bvh格式介绍 bvh格式转换&#xff1a; 生成bvh&#xff1a; 导入导出bvh bvh可视化&#xff1a; H3.6M数据集转bvh pkl转换bvh bvh格式介绍 [转载] BVH文件格式解析 - 知乎 bvh格式转换&#xff1a; https://github.com/Garfield-kh/PoseTriplet/blob/eb93132f991…

μ综合设计控制器

μ综合设计控制器是一种基于μ分析的控制器设计方法&#xff0c;用于提高控制器的鲁棒性和性能。μ分析是一种数学工具&#xff0c;用于描述和比较控制系统在不同参数变化下的性能。通过μ综合设计&#xff0c;可以综合运用各种控制策略&#xff0c;以达到更好的控制效果。 μ…

[Combine 开发] Controlling timing 时间控制

Combine框架里&#xff0c;关于时间控制大致有debounce、delay、measureInterval、throttle、timeout 下面我们分别介绍他们的区别和使用方法 值的我们注意的是Combine中的pipline是异步流&#xff0c;所以这些时间控制的Operator还是很强大的。 debounce 在某些情况下&…

用python实现文本/图片生成视频

使用Python来生成视频通常涉及到使用一些专门的库&#xff0c;比如 OpenCV 或者 moviepy。下面是一个简单的例子&#xff0c;使用OpenCV和PIL&#xff08;Python Imaging Library&#xff09;来创建一个视频。 python复制代码 import cv2 import numpy as np from PIL import …

【双指针】001移动零_C++

题目链接&#xff1a;移动零 目录 题目解析 代码书写 知识补充 题目解析 题目让我们求必须在不复制数组的情况下,编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 这题我们可以用双指针的方法来写&#xff1a; 我们这里将用两个数组下标来…

条码WMS仓储管理系统的价值与优势

在全球化和数字化的时代&#xff0c;企业面临着诸多挑战。在复杂的运营环境中&#xff0c;如何提高运营效率和效果&#xff0c;降低成本&#xff0c;增强竞争力&#xff0c;成为企业关注的焦点。而库存管理作为企业运营的关键环节&#xff0c;其重要性不言而喻。本文将深入探讨…

北交所交易手续费标准?哪家证券公司开通北交所券商交易手续费佣金万2?

北交所&#xff08;Beijing Exchange&#xff09;是指位于中国北京的一家金融交易所。北交所是中国政府为推动金融改革和国际化市场而设立的交易场所。它提供包括股票、债券、期货、外汇等多种金融产品的交易服务。北交所的目标是促进中国金融市场的发展&#xff0c;吸引国内外…

js forEach方法的使

JavaScript中的数组forEach()方法用于对数组中的每个元素执行指定的函数。该方法会遍历数组&#xff0c;并依次将每个元素传递给回调函数进行处理。forEach()方法不会改变原始数组&#xff0c;它只是用于遍历数组的一种方式。 forEach()方法的语法如下&#xff1a; array.for…

golang文件相对路径问题

目录结构 2.具体代码&#xff1a; const dataFile "../data/data.json"_, fileName, _, _ : runtime.Caller(1)dataPath : path.Join(path.Dir(fileName), dataFile)fmt.Println(dataPath)// open filefile, err : os.Open(dataPath)if err ! nil {log.Fatalln(err…

在IntelliJ IDEA中集成SSM项目

SSM项目&#xff1a;springMVC为控制器、spring 为事务层、 MyBatis 负责持久 首先看下集成后项目结构&#xff1a; 1、打开IntelliJ IDEA&#xff0c;点击 "File" -> "New" -> "Project"。 点击Finish&#xff0c;此时我们就已经创建了一…

postman自动化接口测试

背景描述 有一个项目要使用postman进行接口测试&#xff0c;接口所需参数有&#xff1a; appid: 应用标识&#xff1b;sign&#xff1a;请求签名&#xff0c;需要使用HMACSHA1加密算法计算&#xff0c;签名串是&#xff1a;{appid}${url}${stamp}&#xff1b;stamp&#xff1…

Idea如何重置免费使用30天

大家都知道&#xff0c;Idea的使用&#xff0c;不是免费的。需要自己购买&#xff0c;获取证书才能使用&#xff0c;那么怎么无限试用30天呢&#xff01;首次&#xff0c;自己点击 点击Evaluate按钮&#xff0c;就可以免费使用。 过了30天的试用期。重新试用30天。我们需要如下…

6-keto-PGF1α ELISA kit—ENZO LIFE SCIENCE

高灵敏ELISA试剂盒&#xff0c;3小时内可检测低至1.40 pg/ml 6-酮前列腺素F1α 6-酮-前列环素F1α&#xff08;6-keto-PGF1α&#xff09;是前列环素&#xff08;PGI2&#xff09;的稳定水解产物。由于前列环素在缓冲液中的半衰期很短&#xff08;2-3分钟&#xff09;&#xff…

vue2使用electron以及打包配置

1.创建项目 vue create vue-project 2.安装electron vue add electron-builder会自动安装相关依赖 安装成功后会在src下自动生成一个background.js文件就是相应的electron的配置信息 use strictimport { app, protocol, BrowserWindow } from electron import { createProto…

重启阿里云ESC服务器后,数据库与jar包外面无法访问bug

bug 重启了服务器&#xff0c;发现从外面无法连接数据库 原因 使用firewall-cmd --list-all命令查看服务器防火墙的配置&#xff0c;发现没有开启3306端口的开放&#xff0c;虽然我们在安全组设置3306端口但是防火墙没有开启&#xff0c;外面是依然无法访问的。 firewall-cm…

Python网络爬虫进阶:自动切换HTTP代理IP的应用

前言 当你决定做一个网络爬虫的时候&#xff0c;就意味着你要面对一个很大的挑战——IP池和中间件。这两个东西听起来很大上&#xff0c;但其实就是为了让你的爬虫不被封杀了。下面我就来给你讲讲如何搞定这些东西。 第一步&#xff1a;创建爬虫IP池的详细过程 首先&#xf…

ACM:每日学习 状压dp

状压dp&#xff1a; 状压dp是对一般dp的改进&#xff1a; //对于判断多种物品的取法&#xff0c;开多维数组比较麻烦&#xff0c;也不好开&#xff0c;使用二进制来表示物品的取与否。 //使用二进制的话&#xff0c;位运算就更能省时间了&#xff0c;而且更会节省空空间&…

[LitCTF 2023]easy_shark

解压缩&#xff0c;发现需要输入密码&#xff0c;使用010打开&#xff0c;发现frflags和deflags都被修改了&#xff0c;这就会造成压缩包伪加密 把他们都改为0&#xff0c;再打开 将流量包使用wirshark打开 过滤http&#xff0c;并追踪 得到以下信息 看到了一个类似于flag格…