欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java 實現(xiàn)滑動時間窗口限流算法的代碼

 更新時間:2020年11月26日 11:10:44   投稿:mrr  
這篇文章主要介紹了Java 實現(xiàn)滑動時間窗口限流算法的代碼,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

在網(wǎng)上搜滑動時間窗口限流算法,大多都太復雜了,本人實現(xiàn)了個簡單的,先上代碼:

package cn.dijia478.util;

import java.time.LocalTime;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 滑動時間窗口限流工具
 * 本限流工具只適用于單機版,如果想要做全局限流,可以按本程序的思想,用redis的List結構去實現(xiàn)
 *
 * @author dijia478
 * @date 2020-10-13 10:53
 */
public class SlideWindow {

  /** 隊列id和隊列的映射關系,隊列里面存儲的是每一次通過時候的時間戳,這樣可以使得程序里有多個限流隊列 */
  private volatile static Map<String, List<Long>> MAP = new ConcurrentHashMap<>();

  private SlideWindow() {}

  public static void main(String[] args) throws InterruptedException {
    while (true) {
      // 任意10秒內,只允許2次通過
      System.out.println(LocalTime.now().toString() + SlideWindow.isGo("ListId", 2, 10000L));
      // 睡眠0-10秒
      Thread.sleep(1000 * new Random().nextInt(10));
    }
  }

  /**
   * 滑動時間窗口限流算法
   * 在指定時間窗口,指定限制次數(shù)內,是否允許通過
   *
   * @param listId   隊列id
   * @param count   限制次數(shù)
   * @param timeWindow 時間窗口大小
   * @return 是否允許通過
   */
  public static synchronized boolean isGo(String listId, int count, long timeWindow) {
    // 獲取當前時間
    long nowTime = System.currentTimeMillis();
    // 根據(jù)隊列id,取出對應的限流隊列,若沒有則創(chuàng)建
    List<Long> list = MAP.computeIfAbsent(listId, k -> new LinkedList<>());
    // 如果隊列還沒滿,則允許通過,并添加當前時間戳到隊列開始位置
    if (list.size() < count) {
      list.add(0, nowTime);
      return true;
    }

    // 隊列已滿(達到限制次數(shù)),則獲取隊列中最早添加的時間戳
    Long farTime = list.get(count - 1);
    // 用當前時間戳 減去 最早添加的時間戳
    if (nowTime - farTime <= timeWindow) {
      // 若結果小于等于timeWindow,則說明在timeWindow內,通過的次數(shù)大于count
      // 不允許通過
      return false;
    } else {
      // 若結果大于timeWindow,則說明在timeWindow內,通過的次數(shù)小于等于count
      // 允許通過,并刪除最早添加的時間戳,將當前時間添加到隊列開始位置
      list.remove(count - 1);
      list.add(0, nowTime);
      return true;
    }
  }

}

運行可以看到,任意10秒內,通過的次數(shù)不超過2次。或者按照實現(xiàn)原理來說,任意通過2次內的時間差,都不超過10秒:

這里畫圖做說明,為什么這樣可以做到滑動窗口限流,假設10秒內允許通過5次

1.這條線就是隊列l(wèi)ist,當?shù)谝粋€事件進來,隊列大小是0,時間是第1秒:

2.因為size=0,小于5,都沒有到限制的次數(shù),完全不用考慮時間窗口,直接把這次事件的時間戳放到0的位置:

3.第2.8秒的時候,第二個事件來了。因為此時size=1,還是小于5,把這次事件的時間戳放到0的位置,原來第1秒來的事件時間戳會往后移動一格:

4.陸續(xù)的又來了3個事件,隊列大小變成了5,先來的時間戳依次向后移動。此時,第6個事件來了,時間是第8秒:

5.因為size=5,不小于5,此時已經(jīng)達到限制次數(shù),以后都需要考慮時間窗口了。所以取出位置4的時間(離現(xiàn)在最遠的時間),和第6個事件的時間戳做比較:

6.得到的差是7秒,小于時間窗口10秒,說明在10秒內,來的事件個數(shù)大于5了,所以本次不允許通過:

7.接下來即便來上100個事件,只要時間差小于等于10秒,都同上,拒絕通過:

8.第11.1秒,第101次事件過來了。因為size=5,不小于5,所以取出位置4的時間(離現(xiàn)在最遠的時間),和第101個事件的時間戳做比較:

9.得到的差是10.1秒,大于時間窗口10秒,說明在10秒內,來的事件個數(shù)小于等于5了,所以本次允許通過:

10.刪除位置4的時間(離現(xiàn)在最遠的時間),把這次事件的時間戳放到0的位置,后面的時間戳依次向后移動:

往后再來其他事件,就是重復4-10的步驟,即可實現(xiàn),在任意滑動時間窗口內,限制通過的次數(shù)

其本質思想是轉換概念,將原本問題的確定時間大小,進行次數(shù)限制。轉換成確定次數(shù)大小,進行時間限制。

到此這篇關于Java 實現(xiàn)滑動時間窗口限流算法的代碼的文章就介紹到這了,更多相關Java滑動時間窗口限流算法內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • springboot啟動報錯:application?startup?failed問題

    springboot啟動報錯:application?startup?failed問題

    這篇文章主要介紹了springboot啟動報錯:application?startup?failed問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • java必學必會之線程(1)

    java必學必會之線程(1)

    java必學必會之線程第一篇,介紹了線程的基本概念、線程的創(chuàng)建和啟動,想要學好java線程的朋友一定要好好閱讀這篇文章
    2015-12-12
  • Java解析xml文件和json轉換的方法(DOM4j解析)

    Java解析xml文件和json轉換的方法(DOM4j解析)

    相信大家都知道Java解析xml的方法有四種,每種方法都很不錯,今天通過本文給大家分享使用DOM4j進行解析的方法,文章通過兩種方法給大家進行解析,感興趣的朋友一起看看吧
    2021-08-08
  • Spring?Cloud?Gateway集成Sentinel流控詳情

    Spring?Cloud?Gateway集成Sentinel流控詳情

    這篇文章主要介紹了Spring?Cloud?Gateway集成Sentinel流控詳情,Sentinel支持對Spring?Cloud?Gateway、Zuul等主流的API?Gateway進行限流,需要的朋友可以參考一下
    2022-09-09
  • 編程入門:掌握Java運算符技巧

    編程入門:掌握Java運算符技巧

    掌握Java運算符技巧,能讓你的編程之旅輕松許多,本指南將帶你深入了解如何巧妙地使用這些強大的工具,讓代碼不僅高效,還充滿樂趣,跟著我們一起,讓你的Java代碼在運算符的魔法下煥發(fā)新生!
    2023-12-12
  • 一篇文章讓你三分鐘學會Java枚舉

    一篇文章讓你三分鐘學會Java枚舉

    這篇文章主要給大家介紹了如何通過三分鐘學會Java枚舉的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-12-12
  • 如何在JAVA中使用Synchronized

    如何在JAVA中使用Synchronized

    這篇文章主要介紹了如何在JAVA中使用Synchronized,文中代碼非常詳細,對大家的學習有所幫助,感興趣的朋友可以參考下
    2020-06-06
  • java+mysql模擬實現(xiàn)銀行系統(tǒng)

    java+mysql模擬實現(xiàn)銀行系統(tǒng)

    這篇文章主要為大家詳細介紹了java+mysql模擬實現(xiàn)銀行系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • 使用stream的Collectors.toMap()方法常見的問題及解決

    使用stream的Collectors.toMap()方法常見的問題及解決

    這篇文章主要介紹了使用stream的Collectors.toMap()方法常見的問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • java并發(fā)編程Lock鎖可重入性與公平性分析

    java并發(fā)編程Lock鎖可重入性與公平性分析

    這篇文章主要為大家介紹了java并發(fā)編程Lock鎖可重入性與公平性分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-05-05

最新評論