Netty组件优化之时间轮

关于任务调度有多种方式实现,常见的像Timer,ScheduledThreadPoolExecutor,以及时间轮

Timer原理

   timer底层主要是依靠最小堆排序,把任务封装并存储在一个优先级队列中,这个队列底层还是依靠数组和最小堆排序构成。

   Timer timer = new Timer();
        timer.schedule(new java.util.TimerTask() {
            @Override
            public void run() {
                System.out.println("1");
            }
        },1,1);

每次任务提交都要进行一次排序,把延迟时间最短的放在最上边,内部有一个线程不断从队列中获取任务

内部线程的run方法内部每次拿到最小时间的任务,和当前时间比较如果执行时间小于等于当前时间,把taskFired置为true,然后进行判断看是否有那种间隔时间在执行,如果有就再次入队列进行排序.如果不指定默认period为0,只执行一次。如果执行时间还未到就调用wait方法阻塞当前执行任务的线程

每次任务提交时会进行判断如果提交的任务是最小的任务就唤醒此线程这中方法虽然可以完成简单的任务调度但是如果代码报错或者某个任务执行时间过长会导致不能及时的执行。最耗费性能的地方在于每次添加都要进行排序影响性能

ScheduledThreadPoolExecutor原理

底层同样是采用最小堆排序不同的是采用了线程池可以解决单个任务执行时间过长和执行任务异常的情况。但是由于任务的存储采用最小堆排序所以插入和排序都要耗费一定性能

HashedWheelTimer原理

我们可以采用数组实现逻辑的环形结构,每一格代表固定时间,比如一格代表一分钟,只需要把对应的任务构成一个双向链表进行存储。例如一个任务需要15分钟后执行,那么它要放在15对8取模的位置。同时还要维护一个圈数。此时内部线程只需要按时遍历数组同时遍历对应数组的Task链表取出需要执行的任务。

首先要建立一个时间轮对象,HashedWheelTimer.参数分别代表每一格代表的时间,以及时间单位,以及时间轮的大小

这里的大小最终会被调整为离此数字最大的2的整数倍。因为这里涉及到一个取模运算,任何一个数字对2的整数倍取模都等于对2的整数倍减一进行按位与运算,由于位运算效率是大于除法取模运算的,而且可以让Hash散列比较均匀。

首先内部线程的run方法

HashedWheelBucket是数组的类型,其内部维护了一个任务链表。wheel代表创建的数组

重点在于final long deadline = waitForNextTick()方法内部

startTime是线程启动时间每次调用此方法tick都会加一相当于指针移动了一格。其实这里的currentTime代表的是线程运动的总时间。当deadline小于currentTime时说明已经改向下一个时间格子移动了

紧接着run方法内部的transferTimeoutsToBuckets()方法会把任务从队列中拿出

可以看到内部根据时间进行圈数的计算和格子的计算,并添加到对应的格子任务中

再接下来就是run方法处理任务了bucket.expireTimeouts(deadline)

内部遍历每一个任务进行圈数和执行时间的判断是否执行

不过此实现方式的缺点就是如果任务过长就会导致不能按时的执行,但解决了最小堆排序性能占用问题

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JavaAgent 技术原理及实战

JavaAgent 技术原理及实战 1、引子2、JavaAgent 简单示例:方法开始和结束时打印日志2.1 创建 Agent2.2 编写验证 agent 功能的测试类2.2.1 使用JavaAgent 静态加载方式2.2.2 使用 JavaAgent 动态加载方式 2.3、小结 3、JavaAgent3.1 JavaAgent是什么?3.2…

使用Detours进行HOOK

文章目录 Detours介绍Detours配置Detours进行Sleep Hook Detours介绍 Detours是微软研究院开发的一款软件工具,用于Windows平台上的应用程序重定向和修改。 它可以在运行时修改应用程序的执行路径,允许开发人员注入自定义代码来改变应用程序的 行为&…

实验2:CLI的使用与IOS基本命令

1、实验目的 通过本实验可以掌握: CLI的各种工作模式个CLI各种编辑命令“?” 和【Tab】键使用方法IOS基本命令网络设备访问限制查看设备的相关信息 2、实验拓扑 CLI的使用与IOS基本命令使用拓扑如下图所示。 3、实验步骤 (1)CLI模式的切…

docker-compose编排lnmp环境

(1)创建一个目录lnmpcompose [rootlocalhost ~]# tree lnmpcompose lnmpcompose ├── conf │ └── nginx.conf ├── docker-compose.yml └── html ├── index.html ├── mysql.php └── test.php (2)在创建的目…

用ENIGMA-toolbox作图

之前一直使用ggseg呈现结果,最近想试一试其他绘图工具。ENIGMA-toolbox有所了解,绘图功能看起来门槛不高,所以就试着用它呈现一些结果。Matlab版本的ENIGMA-toolbox直接使用就是SurfStat的功能绘图,Python版本的绘图功能应该是根据…

Spring Boot页面国际化

GitHub:SpringBootDemo Gitee:SpringBootDemo 微信公众号: 0 开发环境 JDK:1.8Spring Boot:2.7.18 1 检查配置 确保File -> Settings… -> Editor -> File Encodings 配置中编码为UTF-8,否则…

Python | Leetcode Python题解之第2题两数相加

题目: 题解: # Definition for singly-linked list. # class ListNode: # def __init__(self, val0, nextNone): # self.val val # self.next next class Solution:def addTwoNumbers(self, l1: Optional[ListNode], l2: Optiona…

攻防世界-easyphp

题目信息 题目信息如下&#xff1a; 可以看到&#xff0c;key1和key2的值都为1的时候&#xff0c;才能拿到flag。再网上看&#xff0c;发现key1和key2的值取决于a,b和c的值。 <?php highlight_file(__FILE__); $key1 0; $key2 0;$a $_GET[a]; $b $_GET[b];if(isset($a…

Java编程实战:疫情物资分配系统的设计与实现

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

分治——归并排序算法

例题一 解法&#xff08;归并排序&#xff09;&#xff1a; 算法思路&#xff1a; 归并排序的流程充分的体现了「分⽽治之」的思想&#xff0c;⼤体过程分为两步&#xff1a; ◦ 分&#xff1a;将数组⼀分为⼆为两部分&#xff0c;⼀直分解到数组的⻓度为 1 &#xff0c;使…

vulhub打靶记录——driftingbox

文章目录 主机发现端口扫描目录扫描爆破子域名提权总结 主机发现 使用nmap扫描局域网内存活的主机&#xff0c;命令如下&#xff1a; nmap -sP 192.168.56.0/24192.168.56.1&#xff1a;主机IP&#xff1b;192.168.56.100&#xff1a;DHCP服务器IP&#xff1b;192.168.56.101…

回溯算法|39.组合总和

力扣题目链接 class Solution { private:vector<vector<int>> result;vector<int> path;void backtracking(vector<int>& candidates, int target, int sum, int startIndex) {if (sum > target) {return;}if (sum target) {result.push_back…

IDEA 详细设置

详细设置 如何打开详细配置界面 1、显示工具栏 2、选择详细配置菜单或按钮 系统设置 默认启动项目配置 启动IDEA时&#xff0c;默认自动打开上次开发的项目&#xff1f;还是自己选择&#xff1f; 如果去掉Reopen projects on startup前面的对勾&#xff0c;每次启动IDEA就会…

【软件安装教程】IDEA

【软件安装教程】IDEA 系统: Windows11 64位版本: ideaIC-2023.3.6官方地址: Jetbrains网盘地址: 百度网盘 下载 处于成本考虑就直接用社区版了&#xff0c;如果专业版配置过程都一样 安装 双击下载的文件 根据电脑存储选择一个合适的地址后点击下一步 选择配置&#…

鸿蒙OS(ArkTS) 案例:【使用http网络请求框架加载验证码】

需求&#xff1a;加载验证码&#xff1b;1.下载验证码图像文件&#xff1b;2.获取header里面验证码ID 踩坑--踩坑--踩坑 根据文档使用 request.downloadFile 请求&#xff0c;官方示例: // pages/xxx.ets // 将网络资源文件下载到应用文件目录并读取一段内容 import common …

Mac使用“Workstation”安装双系统

## 选择虚拟机 Mac推荐使用“VMware” 优点 1.个人版是免费的 2.界面清晰&#xff0c;运行流程 3.使用人群广&#xff0c;遇到问题容易解决 版本比较 VMware Workstation Pro 和 VMware Workstation Player 个人使用推荐 VMware Workstation Player &#xff0c;因为个人的…

二十四种设计模式与六大设计原则(四):【状态模式、原型模式、中介者模式、解释器模式、享元模式、备忘录模式】的定义、举例说明、核心思想、适用场景和优缺点

接上次博客&#xff1a;二十四种设计模式与六大设计原则&#xff08;三&#xff09;&#xff1a;【装饰模式、迭代器模式、组合模式、观察者模式、责任链模式、访问者模式】的定义、举例说明、核心思想、适用场景和优缺点-CSDN博客 目录 状态模式【State Pattern】 定义 举…

Python之numpy:常用运算广播机制

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、numpy运算二、常见运算1.ufunc函数2.复合赋值运算符3.判断符 二、聚合函数三、唯一化、集合四、numpy广播机制 一、numpy运算 numpy有两种基本对象&#xff1a…

【linux】AMD GPU和NVIDIA GPU驱动安装

AMD GPUs - Radeon™ PRO W7900的驱动安装过程 要在Linux系统上安装AMD的Radeon™ PRO W7900显卡驱动程序&#xff0c;通常需要执行以下步骤。以下示例基于Ubuntu系统&#xff1b;其他Linux发行版的具体步骤可能有所不同。 1. 更新系统 打开一个终端窗口&#xff0c;并输入…

redis学习-主从复制和哨兵模式

目录 1. 主从复制&#xff0c;读写分离 1.1 介绍 1.2 使用命令介绍 1.3 实现 1.4全量复制和增量复制 2.哨兵模式 1. 主从复制&#xff0c;读写分离 1.1 介绍 指的是将一台redis服务器中的数据复制到其他redis服务器&#xff0c;前者称为主机&#xff0c;后者称为从机&#xf…