日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

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

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

瀏覽:210日期: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
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
亚州精品视频| 日韩毛片一区| 久久一区二区三区电影| 宅男噜噜噜66国产日韩在线观看| 亚洲性视频在线| 免费视频一区二区三区在线观看| 日韩欧美不卡| 亚洲综合电影一区二区三区| 亚洲精品第一| 国产中文欧美日韩在线| 日韩一级不卡| 美女在线视频一区| 五月综合激情| 日韩超碰人人爽人人做人人添| 久久精品国产99国产| 午夜久久福利| 欧美国产视频| 欧美日韩日本国产亚洲在线 | 女生影院久久| 久久高清国产| 精品视频高潮| 欧美日中文字幕| 亚洲精品福利| 欧美三级精品| 国产视频网站一区二区三区| 久久精品国产68国产精品亚洲| 亚洲精品在线二区| 亚洲性色av| 亚洲91网站| 免费污视频在线一区| 青青国产91久久久久久| 激情久久五月| 久久字幕精品一区| 欧美福利专区| 久久99蜜桃| 亚洲色图网站| 极品av在线| 欧美日韩亚洲一区二区三区在线| 亚洲午夜91| 韩日一区二区| 日本久久二区| 国产高清一区| 国产videos久久| 少妇高潮一区二区三区99| 日韩在线第七页| 国产精品v亚洲精品v日韩精品| 免费精品视频| 亚洲h色精品| 精品视频高潮| 久久国产乱子精品免费女| 麻豆精品网站| 日本欧美不卡| 免费观看亚洲天堂| 亚洲精品欧洲| 亚洲一区日韩| 日韩免费久久| 精品久久久网| 国产精品久久久久久久久久久久久久久| 国产亚洲永久域名| 五月激情久久| 精品网站999| 国产欧美日韩一区二区三区四区| 宅男噜噜噜66国产日韩在线观看| 午夜影院一区| 久久亚洲黄色| 国产日韩欧美中文在线| 免费成人在线观看| 亚洲午夜在线| 日韩中文在线电影| 国产在线日韩精品| 国产精品毛片久久久| 视频一区中文字幕精品| 久久国产成人| 黄色成人精品网站| 亚洲二区精品| 色天使综合视频| 久久久男人天堂| 国产一区精品福利| 精品亚洲a∨一区二区三区18| 国产乱子精品一区二区在线观看 | 久久夜色精品| 亚洲激情五月| 久久精品高清| 欧美片第1页| 日本不良网站在线观看| 精品国产18久久久久久二百| 国产精品nxnn| 欧美a级一区二区| 国产精品久久久久久久久久齐齐| 日韩高清在线不卡| 日本麻豆一区二区三区视频| 亚洲视频二区| 久久亚洲欧美| 亚洲人www| 日本中文字幕一区二区| 欧美日韩午夜电影网| 国产剧情一区| 精品视频在线你懂得| 国产一区日韩| 婷婷激情一区| 欧美在线影院| 喷白浆一区二区| 在线一区二区三区视频| 亚洲最新av| 日韩精品视频网站| 国产美女久久| 高清一区二区三区| 97精品中文字幕| 日韩在线观看一区| 亚洲精品电影| 亚洲三级毛片| 国产精品密蕾丝视频下载| 国产一区二区三区黄网站| 捆绑调教日本一区二区三区| 99视频精品全部免费在线视频| 国产一区亚洲| 免费在线观看精品| 亚欧洲精品视频在线观看| 久久国产精品免费一区二区三区 | 男女性色大片免费观看一区二区 | 欧美亚洲专区| 国产色噜噜噜91在线精品| 国产精品视频首页| 日韩欧美字幕| 99视频一区| 亚洲男人在线| 久久永久免费| 久久视频精品| 在线国产日韩| 久久中文欧美| 亚洲成人精选| 久久激五月天综合精品| 久久精品一区二区国产| 欧美色图一区| 日韩国产一区二| 一区二区三区四区日本视频| 精品欧美久久| 日韩三级视频| 久久久久久色 | 国产一区二区视频在线看| 99久久久久| 日本亚洲视频在线| 国产一区国产二区国产三区| 欧美日韩在线播放视频| 色狠狠一区二区三区| 精品一二三区| 亚洲综合欧美| 另类欧美日韩国产在线| 亚洲欧洲一区| 麻豆一区二区在线| 亚洲经典在线| 精品三级久久久| 亚洲一区国产| 水蜜桃久久夜色精品一区| 丝瓜av网站精品一区二区| 国产精品v日韩精品v欧美精品网站| 中文字幕系列一区| 日本aⅴ亚洲精品中文乱码| 视频在线不卡免费观看| 一区二区高清| 日韩欧美国产精品综合嫩v| 最新国产精品| 欧美日韩在线观看首页| 综合国产精品| 日本高清不卡一区二区三区视频| 日韩精品成人| 激情久久久久久| 久久成人高清| 另类国产ts人妖高潮视频| 国产色播av在线| 蜜桃久久精品一区二区| 日韩中文影院| 国产精品主播| 亚洲欧洲另类| 91欧美日韩| 日本成人在线视频网站| 欧美日韩国产在线一区| 久久久久久久欧美精品| 久久久久久黄| 欧美另类中文字幕| 午夜精品免费| 国产成人精品一区二区三区在线| 亚洲三级av| 好看不卡的中文字幕| 国产精品成人a在线观看| 日韩中文字幕| 亚洲专区一区| 欧美色图国产精品| 国产一区二区三区四区大秀| 日韩精品福利一区二区三区| 欧美在线资源| 正在播放日韩精品| 国产亚洲久久| 亚洲精品三级| 红桃视频亚洲| 国产一区日韩一区| 在线观看精品| 日韩电影在线视频| 久久影视三级福利片| 日韩高清二区|