限流算法java实现

参考教程:2小时吃透4种分布式限流算法

1.计数器限流

java 复制代码
public class CounterLimiter {

    // 开始时间
    private static long startTime = System.currentTimeMillis();
    // 时间间隔,单位为ms
    private long interval = 1000L;
    // 限制访问次数
    private int limitCount = 2;
    // 访问次数
    private int reqCount = 0;

    private synchronized boolean tryAcquire(){
        long nowTime = System.currentTimeMillis();
        if(nowTime < startTime + interval){
            if(reqCount + 1 > limitCount){
                System.out.println(Thread.currentThread().getName() + "被限流了");
                return true;
            }
            reqCount++;
            System.out.println(Thread.currentThread().getName() + "通过了");
            return false;
        }else {
            reqCount = 1;
            startTime = nowTime;
            System.out.println(Thread.currentThread().getName() + "通过了");
            return false;
        }
    }

    public static void main(String[] args) {
        CounterLimiter counterLimiter = new CounterLimiter();
        for (int i = 0; i < 10; i++) {
            new Thread(() ->{
                counterLimiter.tryAcquire();
            }).start();
        }
    }

}

2.滑动时间窗口限流

java 复制代码
import java.util.LinkedList;

public class SlidingTimeWindowLimiter {
    // 请求数量
    private int reqCount;
    // 窗口集合
    private LinkedList<Integer> slots = new LinkedList<>();
    // 限制访问量
    private int limitNum = 2;
    // 窗口数量
    private int windowNum = 100;
    // 每个窗口的时间范围,单位ms
    private long windowLength = 100L;

    public synchronized Boolean limit(){
        if(reqCount + 1 > limitNum){
            System.out.println(Thread.currentThread().getName() + ": 被拦截了");
            return true;
        }
        reqCount++;
        slots.set(slots.size() - 1, slots.peekLast() + 1);
        System.out.println(Thread.currentThread().getName() + ": 通过了");
        return false;
    }
    public SlidingTimeWindowLimiter(){
        slots.addLast(0);
        new Thread(() -> {
            while (true){
                try {
                    Thread.sleep(windowLength);
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
                slots.addLast(0);
                if(slots.size() > windowNum){
                    reqCount = reqCount - slots.peekLast();
                    slots.removeLast();
                    System.out.println("滑动格子:" + reqCount);
                }
            }
        }).start();

    }

    public static void main(String[] args) {
        SlidingTimeWindowLimiter slidingTimeWindowLimiter = new SlidingTimeWindowLimiter();
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                slidingTimeWindowLimiter.limit();
            }).start();
        }
    }

}

3.漏桶算法

java 复制代码
public class LeakyBucketLimiter {
    // 初始时间
    private long timestamp = System.currentTimeMillis();
    // 漏桶容量
    private long capacity = 5;
    // 流出速率
    private long rate = 10;
    // 桶内有多少请求
    private long water = 0;

    public synchronized Boolean limit(){
        long now = System.currentTimeMillis();
        water = Math.max(0, water - (now - timestamp) / 1000 * rate);
        timestamp = now;
        if((water + 1) <= capacity){
            water++;
            System.out.println(Thread.currentThread().getName() + "通过了");
            return false;
        }else{
            System.out.println(Thread.currentThread().getName() + "被拦截了");
            return true;
        }
    }

    public static void main(String[] args) {
        LeakyBucketLimiter counterLimiter = new LeakyBucketLimiter();
        for (int i = 0; i < 10; i++) {
            new Thread(() ->{
                counterLimiter.limit();
            }).start();
        }
    }

}

4.令牌桶算法

java 复制代码
public class TokenBucketLimiter {
    // 初始时间
    private long timeStamp = System.currentTimeMillis();
    // 令牌桶容量
    private long capacity = 5;
    // 每秒生成令牌的数量
    private long rate  = 2;
    // 桶内的令牌数
    private long tokens = 0;

    public synchronized Boolean limit(){
        long now = System.currentTimeMillis();
        tokens = Math.min(capacity, tokens + (now - timeStamp) * rate);
        timeStamp = now;
        // 没有令牌了
        if(tokens < 1){
            System.out.println(Thread.currentThread().getName() + "被拦截了");
            return true;
        }else {
            tokens--;
            System.out.println(Thread.currentThread().getName() + "通过了");
            return false;
        }
    }
    public static void main(String[] args) {
        TokenBucketLimiter slidingTimeWindowLimiter = new TokenBucketLimiter();
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                slidingTimeWindowLimiter.limit();
            }).start();
        }
    }
}
相关推荐
无敌最俊朗@1 小时前
STL-vector面试剖析(面试复习4)
java·面试·职场和发展
PPPPickup1 小时前
easychat项目复盘---获取联系人列表,联系人详细,删除拉黑联系人
java·前端·javascript
LiamTuc1 小时前
Java构造函数
java·开发语言
长安er1 小时前
LeetCode 206/92/25 链表翻转问题-“盒子-标签-纸条模型”
java·数据结构·算法·leetcode·链表·链表翻转
菜鸟plus+2 小时前
N+1查询
java·服务器·数据库
我要添砖java2 小时前
《JAVAEE》网络编程-什么是网络?
java·网络·java-ee
CoderYanger2 小时前
动态规划算法-01背包问题:50.分割等和子集
java·算法·leetcode·动态规划·1024程序员节
菜鸟233号3 小时前
力扣513 找树左下角的值 java实现
java·数据结构·算法·leetcode
Neoest4 小时前
【EasyExcel 填坑日记】“Syntax error on token )“: 一次编译错误在逃 Runtime 的灵异事件
java·eclipse·编辑器
自在极意功。4 小时前
Web开发中的分层解耦
java·microsoft·web开发·解耦