电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

java簡單手寫版本實現時間輪算法

瀏覽:99日期:2022-08-14 17:38:25
時間輪

關于時間輪的介紹,網上有很多,這里就不重復了

核心思想 一個環形數組存儲時間輪的所有槽(看你的手表),每個槽對應當前時間輪的最小精度 超過當前時間輪最大表示范圍的會被丟到上層時間輪,上層時間輪的最小精度即為下層時間輪能表達的最大時間(時分秒概念) 每個槽對應一個環形鏈表存儲該時間應該被執行的任務 需要一個線程去驅動指針運轉,獲取到期任務

以下給出java 簡單手寫版本實現

代碼實現

時間輪主數據結構

/** * @author apdoer * @version 1.0 * @date 2021/3/22 19:31 */@Slf4jpublic class TimeWheel { /** * 一個槽的時間間隔(時間輪最小刻度) */ private long tickMs; /** * 時間輪大小(槽的個數) */ private int wheelSize; /** * 一輪的時間跨度 */ private long interval; private long currentTime; /** * 槽 */ private TimerTaskList[] buckets; /** * 上層時間輪 */ private volatile TimeWheel overflowWheel; /** * 一個timer只有一個delayqueue */ private DelayQueue<TimerTaskList> delayQueue; public TimeWheel(long tickMs, int wheelSize, long currentTime, DelayQueue<TimerTaskList> delayQueue) { this.currentTime = currentTime; this.tickMs = tickMs; this.wheelSize = wheelSize; this.interval = tickMs * wheelSize; this.buckets = new TimerTaskList[wheelSize]; this.currentTime = currentTime - (currentTime % tickMs); this.delayQueue = delayQueue; for (int i = 0; i < wheelSize; i++) { buckets[i] = new TimerTaskList(); } } public boolean add(TimerTaskEntry entry) { long expiration = entry.getExpireMs(); if (expiration < tickMs + currentTime) { //到期了 return false; } else if (expiration < currentTime + interval) { //扔進當前時間輪的某個槽里,只有時間大于某個槽,才會放進去 long virtualId = (expiration / tickMs); int index = (int) (virtualId % wheelSize); TimerTaskList bucket = buckets[index]; bucket.addTask(entry); //設置bucket 過期時間 if (bucket.setExpiration(virtualId * tickMs)) {//設好過期時間的bucket需要入隊delayQueue.offer(bucket);return true; } } else { //當前輪不能滿足,需要扔到上一輪 TimeWheel timeWheel = getOverflowWheel(); return timeWheel.add(entry); } return false; } private TimeWheel getOverflowWheel() { if (overflowWheel == null) { synchronized (this) {if (overflowWheel == null) { overflowWheel = new TimeWheel(interval, wheelSize, currentTime, delayQueue);} } } return overflowWheel; } /** * 推進指針 * * @param timestamp */ public void advanceLock(long timestamp) { if (timestamp > currentTime + tickMs) { currentTime = timestamp - (timestamp % tickMs); if (overflowWheel != null) {this.getOverflowWheel().advanceLock(timestamp); } } }}

定時器接口

/** * 定時器 * @author apdoer * @version 1.0 * @date 2021/3/22 20:30 */public interface Timer { /** * 添加一個新任務 * * @param timerTask */ void add(TimerTask timerTask); /** * 推動指針 * * @param timeout */ void advanceClock(long timeout); /** * 等待執行的任務 * * @return */ int size(); /** * 關閉服務,剩下的無法被執行 */ void shutdown();}

定時器實現

/** * @author apdoer * @version 1.0 * @date 2021/3/22 20:33 */@Slf4jpublic class SystemTimer implements Timer { /** * 底層時間輪 */ private TimeWheel timeWheel; /** * 一個Timer只有一個延時隊列 */ private DelayQueue<TimerTaskList> delayQueue = new DelayQueue<>(); /** * 過期任務執行線程 */ private ExecutorService workerThreadPool; /** * 輪詢delayQueue獲取過期任務線程 */ private ExecutorService bossThreadPool; public SystemTimer() { this.timeWheel = new TimeWheel(1, 20, System.currentTimeMillis(), delayQueue); this.workerThreadPool = Executors.newFixedThreadPool(100); this.bossThreadPool = Executors.newFixedThreadPool(1); //20ms推動一次時間輪運轉 this.bossThreadPool.submit(() -> { for (; ; ) {this.advanceClock(20); } }); } public void addTimerTaskEntry(TimerTaskEntry entry) { if (!timeWheel.add(entry)) { //已經過期了 TimerTask timerTask = entry.getTimerTask(); log.info('=====任務:{} 已到期,準備執行============',timerTask.getDesc()); workerThreadPool.submit(timerTask); } } @Override public void add(TimerTask timerTask) { log.info('=======添加任務開始====task:{}', timerTask.getDesc()); TimerTaskEntry entry = new TimerTaskEntry(timerTask, timerTask.getDelayMs() + System.currentTimeMillis()); timerTask.setTimerTaskEntry(entry); addTimerTaskEntry(entry); } /** * 推動指針運轉獲取過期任務 * * @param timeout 時間間隔 * @return */ @Override public synchronized void advanceClock(long timeout) { try { TimerTaskList bucket = delayQueue.poll(timeout, TimeUnit.MILLISECONDS); if (bucket != null) {//推進時間timeWheel.advanceLock(bucket.getExpiration());//執行過期任務(包含降級)bucket.clear(this::addTimerTaskEntry); } } catch (InterruptedException e) { log.error('advanceClock error'); } } @Override public int size() { //todo return 0; } @Override public void shutdown() { this.bossThreadPool.shutdown(); this.workerThreadPool.shutdown(); this.timeWheel = null; }}

存儲任務的環形鏈表

/** * @author apdoer * @version 1.0 * @date 2021/3/22 19:26 */@Data@Slf4jclass TimerTaskList implements Delayed { /** * TimerTaskList 環形鏈表使用一個虛擬根節點root */ private TimerTaskEntry root = new TimerTaskEntry(null, -1); { root.next = root; root.prev = root; } /** * bucket的過期時間 */ private AtomicLong expiration = new AtomicLong(-1L); public long getExpiration() { return expiration.get(); } /** * 設置bucket的過期時間,設置成功返回true * * @param expirationMs * @return */ boolean setExpiration(long expirationMs) { return expiration.getAndSet(expirationMs) != expirationMs; } public boolean addTask(TimerTaskEntry entry) { boolean done = false; while (!done) { //如果TimerTaskEntry已經在別的list中就先移除,同步代碼塊外面移除,避免死鎖,一直到成功為止 entry.remove(); synchronized (this) {if (entry.timedTaskList == null) { //加到鏈表的末尾 entry.timedTaskList = this; TimerTaskEntry tail = root.prev; entry.prev = tail; entry.next = root; tail.next = entry; root.prev = entry; done = true;} } } return true; } /** * 從 TimedTaskList 移除指定的 timerTaskEntry * * @param entry */ public void remove(TimerTaskEntry entry) { synchronized (this) { if (entry.getTimedTaskList().equals(this)) {entry.next.prev = entry.prev;entry.prev.next = entry.next;entry.next = null;entry.prev = null;entry.timedTaskList = null; } } } /** * 移除所有 */ public synchronized void clear(Consumer<TimerTaskEntry> entry) { TimerTaskEntry head = root.next; while (!head.equals(root)) { remove(head); entry.accept(head); head = root.next; } expiration.set(-1L); } @Override public long getDelay(TimeUnit unit) { return Math.max(0, unit.convert(expiration.get() - System.currentTimeMillis(), TimeUnit.MILLISECONDS)); } @Override public int compareTo(Delayed o) { if (o instanceof TimerTaskList) { return Long.compare(expiration.get(), ((TimerTaskList) o).expiration.get()); } return 0; }}

存儲任務的容器entry

/** * @author apdoer * @version 1.0 * @date 2021/3/22 19:26 */@Dataclass TimerTaskEntry implements Comparable<TimerTaskEntry> { private TimerTask timerTask; private long expireMs; volatile TimerTaskList timedTaskList; TimerTaskEntry next; TimerTaskEntry prev; public TimerTaskEntry(TimerTask timedTask, long expireMs) { this.timerTask = timedTask; this.expireMs = expireMs; this.next = null; this.prev = null; } void remove() { TimerTaskList currentList = timedTaskList; while (currentList != null) { currentList.remove(this); currentList = timedTaskList; } } @Override public int compareTo(TimerTaskEntry o) { return ((int) (this.expireMs - o.expireMs)); }}

任務包裝類(這里也可以將工作任務以線程變量的方式去傳入)

@Data@Slf4jclass TimerTask implements Runnable { /** * 延時時間 */ private long delayMs; /** * 任務所在的entry */ private TimerTaskEntry timerTaskEntry; private String desc; public TimerTask(String desc, long delayMs) { this.desc = desc; this.delayMs = delayMs; this.timerTaskEntry = null; } public synchronized void setTimerTaskEntry(TimerTaskEntry entry) { // 如果這個timetask已經被一個已存在的TimerTaskEntry持有,先移除一個 if (timerTaskEntry != null && timerTaskEntry != entry) { timerTaskEntry.remove(); } timerTaskEntry = entry; } public TimerTaskEntry getTimerTaskEntry() { return timerTaskEntry; } @Override public void run() { log.info('============={}任務執行', desc); }}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持好吧啦網。

標簽: Java
相關文章:
主站蜘蛛池模板: 特种阀门-调节阀门-高温熔盐阀-镍合金截止阀-钛阀门-高温阀门-高性能蝶阀-蒙乃尔合金阀门-福建捷斯特阀门制造有限公司 | 好物生环保网、环保论坛 - 环保人的学习交流平台 | 青岛美佳乐清洁工程有限公司|青岛油烟管道清洗|酒店|企事业单位|学校工厂厨房|青岛油烟管道清洗 插针变压器-家用电器变压器-工业空调变压器-CD型电抗器-余姚市中驰电器有限公司 | 爱德华真空泵油/罗茨泵维修,爱发科-比其尔产品供应东莞/杭州/上海等全国各地 | RFID电子标签厂家-上海尼太普电子有限公司 | 卫浴散热器,卫浴暖气片,卫生间背篓暖气片,华圣格浴室暖气片 | 聚合氯化铝价格_聚合氯化铝厂家_pac絮凝剂-唐达净水官网 | 衬氟旋塞阀-卡套旋塞阀-中升阀门首页 | 活性炭-果壳木质煤质柱状粉状蜂窝活性炭厂家价格多少钱 | 长沙广告公司|长沙广告制作设计|长沙led灯箱招牌制作找望城湖南锦蓝广告装饰工程有限公司 | 山东风淋室_201/304不锈钢风淋室净化设备厂家-盛之源风淋室厂家 翻斗式矿车|固定式矿车|曲轨侧卸式矿车|梭式矿车|矿车配件-山东卓力矿车生产厂家 | 一级建造师培训_一建培训机构_中建云筑建造师培训网校 | 专注提供国外机电设备及配件-工业控制领域一站式服务商-深圳市华联欧国际贸易有限公司 | 方源木业官网-四川木门-全国木门专业品牌 | 铝合金线槽_铝型材加工_空调挡水板厂家-江阴炜福金属制品有限公司 | 网站建设-临朐爱采购-抖音运营-山东兆通网络科技 | 电杆荷载挠度测试仪-电杆荷载位移-管桩测试仪-北京绿野创能机电设备有限公司 | 浙江宝泉阀门有限公司| 成都治疗尖锐湿疣比较好的医院-成都治疗尖锐湿疣那家医院好-成都西南皮肤病医院 | 长信科技产业园官网_西安厂房_陕西标准工业厂房 | 双能x射线骨密度检测仪_dxa骨密度仪_双能x线骨密度仪_品牌厂家【品源医疗】 | 内六角扳手「厂家」-温州市威豪五金工具有限公司 | 微波消解仪器_智能微波消解仪报价_高压微波消解仪厂家_那艾 | 广州云仓代发-昊哥云仓专业电商仓储托管外包代发货服务 | 山东信蓝建设有限公司官网| DAIKIN电磁阀-意大利ATOS电磁阀-上海乾拓贸易有限公司 | CE认证_产品欧盟ROHS-REACH检测机构-商通检测 | 贝壳粉涂料-内墙腻子-外墙腻子-山东巨野七彩贝壳漆业中心 | 儿童乐园|游乐场|淘气堡招商加盟|室内儿童游乐园配套设备|生产厂家|开心哈乐儿童乐园 | 山东PE给水管厂家,山东双壁波纹管,山东钢带增强波纹管,山东PE穿线管,山东PE农田灌溉管,山东MPP电力保护套管-山东德诺塑业有限公司 | 京港视通报道-质量走进大江南北-京港视通传媒[北京]有限公司 | 动力配电箱-不锈钢配电箱-高压开关柜-重庆宇轩机电设备有限公司 聚天冬氨酸,亚氨基二琥珀酸四钠,PASP,IDS - 远联化工 | 地图标注|微信高德百度地图标注|地图标记-做地图[ZuoMap.com] | 线材成型机,线材折弯机,线材成型机厂家,贝朗自动化设备有限公司1 | 旋振筛|圆形摇摆筛|直线振动筛|滚筒筛|压榨机|河南天众机械设备有限公司 | pbootcms网站模板|织梦模板|网站源码|jquery建站特效-html5模板网 | 模具钢_高速钢_不锈钢-万利钢金属材料 | 陕西安闸机-伸缩门-车牌识别-广告道闸——捷申达门业科技 | 天津货架厂_穿梭车货架_重型仓储货架_阁楼货架定制-天津钢力仓储货架生产厂家_天津钢力智能仓储装备 | 铝合金脚手架厂家-专注高空作业平台-深圳腾达安全科技 | 深圳办公室装修,办公楼/写字楼装修设计,一级资质 - ADD写艺 |