最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java單機滑動窗口限流器的實現(xiàn)

 更新時間:2026年03月22日 14:59:59   作者:編碼忘我  
本文主要介紹了java單機滑動窗口限流器的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

下面使用 ConcurrentHashMap + ConcurrentLinkedDeque 實現(xiàn)一個滑動窗口限流器,限制在 10 秒內(nèi)最多 N 次請求(例如 5 次)。這種方案只依賴本地內(nèi)存,適合單機限流場景。

實現(xiàn)原理

  • 為每個用戶(或 IP)維護一個 雙端隊列,存儲每次請求的時間戳(毫秒)。

  • 每次請求時,先清理隊列中 超過 10 秒 的舊時間戳,再判斷隊列大小是否小于閾值:

    • 若小于,則添加當前時間戳,返回 允許;
    • 否則,返回 限流。
  • 使用 ConcurrentHashMap 保證對用戶 Key 的線程安全,使用 synchronized 對每個隊列做同步,避免并發(fā)修改。

代碼實現(xiàn)

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.TimeUnit;
/**
 * 基于 Map 的滑動窗口限流器(10秒限頻)
 */
public class LocalSlidingWindowRateLimiter {
    // 存儲每個用戶的請求時間戳隊列
    private final Map<String, ConcurrentLinkedDeque<Long>> userQueueMap = new ConcurrentHashMap<>();
    private final int windowSeconds;   // 窗口大?。耄?
    private final int maxRequests;     // 窗口內(nèi)最大請求數(shù)
    public LocalSlidingWindowRateLimiter(int windowSeconds, int maxRequests) {
        this.windowSeconds = windowSeconds;
        this.maxRequests = maxRequests;
    }
    /**
     * 檢查是否允許請求
     * @param key 限流標識(如 userId、ip)
     * @return true 允許,false 被限流
     */
    public boolean allowRequest(String key) {
        long now = System.currentTimeMillis();
        long windowStart = now - TimeUnit.SECONDS.toMillis(windowSeconds);
        // 獲取或創(chuàng)建該用戶的隊列
        ConcurrentLinkedDeque<Long> deque = userQueueMap.computeIfAbsent(key,
                k -> new ConcurrentLinkedDeque<>());
        // 對隊列加鎖,保證清理和添加的原子性
        synchronized (deque) {
            // 1. 清理過期記錄(窗口外的舊時間戳)
            while (!deque.isEmpty() && deque.peekFirst() < windowStart) {
                deque.pollFirst();
            }
            // 2. 判斷是否超過閾值
            if (deque.size() < maxRequests) {
                // 允許請求,記錄當前時間戳
                deque.addLast(now);
                return true;
            } else {
                return false;
            }
        }
    }
    // 可選:定期清理無數(shù)據(jù)的用戶 Key,避免內(nèi)存泄漏(可以用 ScheduledExecutorService 定時清理)
    public void cleanEmptyKeys() {
        userQueueMap.entrySet().removeIf(entry -> entry.getValue().isEmpty());
    }
}

使用示例

public class Main {
    public static void main(String[] args) throws InterruptedException {
        // 限流規(guī)則:10秒內(nèi)最多5次請求
        LocalSlidingWindowRateLimiter limiter = new LocalSlidingWindowRateLimiter(10, 5);
        String userId = "user_123";
        for (int i = 0; i < 10; i++) {
            boolean allowed = limiter.allowRequest(userId);
            System.out.println("請求 " + (i + 1) + ":" + (allowed ? "通過" : "限流"));
            Thread.sleep(1000); // 模擬間隔 1 秒
        }
    }
}

輸出示例(第 6 次請求被限流,因為 10 秒內(nèi)已有 5 次):

請求 1:通過
請求 2:通過
請求 3:通過
請求 4:通過
請求 5:通過
請求 6:限流
請求 7:限流
...

注意事項

  1. 內(nèi)存清理:長期不活動的用戶 Key 會殘留隊列對象,建議定時調(diào)用 cleanEmptyKeys() 清理。
  2. 并發(fā)安全:每個隊列使用 synchronized 鎖保證原子操作,鎖粒度小,性能較高。
  3. 時間精度:使用毫秒級時間戳,滑動窗口邊界判斷精確。
  4. 適用場景:單機應用、對分布式一致性要求不高的限流場景。

到此這篇關(guān)于java單機滑動窗口限流器的實現(xiàn)的文章就介紹到這了,更多相關(guān)java 滑動窗口限流器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java解析xml之dom解析xml示例分享

    java解析xml之dom解析xml示例分享

    DOM將整個XML文件加載到內(nèi)存中,并構(gòu)建出節(jié)點樹;應用程序可以通過遍歷節(jié)點樹的方式來解析XML文件中的各個節(jié)點、屬性等信息; 這種方式便于對XML節(jié)點的添加修改等,而且解析也很方便,然后它比較耗費內(nèi)存,解析速度也不快,下面看使用示例吧
    2014-01-01
  • 關(guān)于Spring的@Autowired依賴注入常見錯誤的總結(jié)

    關(guān)于Spring的@Autowired依賴注入常見錯誤的總結(jié)

    有時我們會使用@Autowired自動注入,同時也存在注入到集合、數(shù)組等復雜類型的場景。這都是方便寫 bug 的場景,本篇文章帶你了解Spring @Autowired依賴注入的坑
    2021-09-09
  • Java Swing CardLayout卡片布局的實現(xiàn)示例

    Java Swing CardLayout卡片布局的實現(xiàn)示例

    這篇文章主要介紹了Java Swing CardLayout卡片布局的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-12-12
  • 全面解析Java設計模式之單例模式

    全面解析Java設計模式之單例模式

    這篇文章主要幫助大家全面解析Java設計模式之單例模式,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • spring boot+redis 監(jiān)聽過期Key的操作方法

    spring boot+redis 監(jiān)聽過期Key的操作方法

    這篇文章主要介紹了spring boot+redis 監(jiān)聽過期Key,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-08-08
  • Java數(shù)據(jù)結(jié)構(gòu)之數(shù)組(動力節(jié)點之Java學院整理)

    Java數(shù)據(jù)結(jié)構(gòu)之數(shù)組(動力節(jié)點之Java學院整理)

    這篇文章主要介紹了Java數(shù)據(jù)結(jié)構(gòu)之數(shù)組(動力節(jié)點之Java學院整理)的相關(guān)資料,包括創(chuàng)建和內(nèi)存分配,數(shù)組封裝后的使用等,需要的朋友參考下吧
    2017-04-04
  • Spring jdbc具名參數(shù)使用方法詳解

    Spring jdbc具名參數(shù)使用方法詳解

    這篇文章主要介紹了Spring jdbc具名參數(shù)使用方法詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-08-08
  • idea中cherry pick的用法

    idea中cherry pick的用法

    Cherry-Pick可以將一個分支的某些commit,合并到另一個分支,本文給大家分享idea中cherry pick的用法,感興趣的朋友跟隨小編一起看看吧
    2023-08-08
  • mybatis-plus使用@Delete注解批量刪除實現(xiàn)方式

    mybatis-plus使用@Delete注解批量刪除實現(xiàn)方式

    文章介紹了如何使用@Delete注解進行批量刪除操作,包括控制器調(diào)用、接口實現(xiàn)和效果圖展示,作者分享了個人經(jīng)驗,并鼓勵大家參考和點贊支持
    2026-02-02
  • java 商戶PC端接入支付寶支付的實現(xiàn)方法

    java 商戶PC端接入支付寶支付的實現(xiàn)方法

    這篇文章主要介紹了java 商戶PC端接入支付寶支付的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-08-08

最新評論

民权县| 吉木乃县| 巢湖市| 吕梁市| 合川市| 迁西县| 互助| 年辖:市辖区| 繁峙县| 常山县| 于田县| 会同县| 石嘴山市| 安泽县| 罗甸县| 辽阳市| 越西县| 嵊州市| 腾冲县| 阜新市| 嫩江县| 汝城县| 北京市| 翁牛特旗| 昆明市| 甘肃省| 信宜市| 汽车| 张家界市| 湄潭县| 洛隆县| 无极县| 香格里拉县| 吉林省| 思茅市| 客服| 保亭| 山阴县| 古交市| 徐闻县| 灵石县|