限流器 + 定时任务 – 轮询扫描法(环形队列)

RateLimiter

RateLimiter 是 Guava 库中的一个类,用于实现限流功能。它基于令牌桶算法,通过控制生成和消费令牌的速率来限制对某个资源的访问频率。

主要作用是控制对资源的访问速率,可以限制每秒访问的请求数量或每秒处理的任务数量,以避免资源被过度使用或超负荷运行。

使用 RateLimiter 可以实现以下功能:

  1. 平滑限流:RateLimiter 可以根据设定的速率,以平滑的方式限制对资源的访问。它可以确保访问速率平稳,并且在突发流量下也能控制访问频率,避免资源被过度耗尽。
  2. 非阻塞限流:RateLimiter 采用非阻塞的方式进行限流,不会阻塞等待请求或任务的执行。它通过返回一个等待时间,让调用方自行决定是否等待,以控制访问频率。

通过适当配置 RateLimiter 的速率参数,可以灵活地控制对资源的访问速率,从而实现对系统的流量控制。

package com.example.common.util;

import com.google.common.util.concurrent.RateLimiter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * RateLimiter -- 限流
 * 定时任务 -- 轮询扫描法
 *
 * @author wanglizhi
 * @date 2023/7/17 14:01
 */
@Component
public class CurrentLimiter {
    /**
     * 定义限流器
     */
    private final static RateLimiter RATE_LIMITER = RateLimiter.create(1);
    private Integer pointer = 0;

    @Autowired
    @Qualifier(value = "systemExecutor")
    Executor executor;

    //    @PostConstruct
    public void main() {
        for (int i = 0; i < 5; i++) {
            executor.execute(() -> {
                System.out.println(Thread.currentThread().getName());
                RATE_LIMITER.acquire();
                System.out.println(new Date());
            });
        }
    }

    /**
     * 轮询扫描法 -- 使用Timer(ali建议使用ScheduledExecutorService代替Timer)
     */
//    @PostConstruct
    public void pollingScanningMethod() {
        Timer timer = new Timer();
        List<Map<Integer, String>> list = new ArrayList<>(10);
        for (int i = 0; i < 10; i++) {
            Map<Integer, String> map = new HashMap<>();
            for (int j = 0; j < 10; j++) {
                map.put(j, String.valueOf(j));
            }
            list.add(map);
        }

        // 创建一个定时任务
        TimerTask task = new TimerTask() {
            @Override
            public synchronized void run() {
                List<Integer> removeKey = new ArrayList<>();
                // 在这里定义需要执行的任务逻辑
                list.get(pointer).forEach((key, value) -> {
                    if (key % 2 == 0) {
                        removeKey.add(key);
                    }
                });

                removeKey.forEach(key -> {
                    list.get(pointer).remove(key);
                    System.out.println("删除--" + "pointer:" + pointer + "key:" + key);
                });

                if (pointer < 9) {
                    pointer++;
                } else {
                    pointer = 0;
                }

            }
        };
        // 启动定时器,每隔一定时间执行任务
        timer.schedule(task, 0, 1000); // 在0毫秒后开始执行任务,每隔1000毫秒重复执行

        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(list);
        // 停止定时器
        timer.cancel();
    }

    /**
     * 轮询扫描法 --使用ScheduledExecutorService
     */
    @PostConstruct
    public void pollingScanningMethod1() {
        List<Map<Integer, String>> list = new ArrayList<>(10);
        for (int i = 0; i < 10; i++) {
            Map<Integer, String> map = new HashMap<>();
            for (int j = 0; j < 10; j++) {
                map.put(j, String.valueOf(j));
            }
            list.add(map);
        }

        // 创建一个 ScheduledExecutorService
        ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
        Runnable task = () -> {
            List<Integer> removeKey = new ArrayList<>();
            list.get(pointer).forEach((key, value) -> {
                if (key % 2 == 0) {
                    removeKey.add(key);
                }
            });

            removeKey.forEach(key -> {
                list.get(pointer).remove(key);
                System.out.println("删除--" + "pointer:" + pointer + "key:" + key);
            });

            if (pointer < 9) {
                pointer++;
            } else {
                pointer = 0;
            }
        };

        // 启动定时器,每隔一定时间执行任务
        executor.scheduleWithFixedDelay(task, 0, 1, TimeUnit.SECONDS);
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(list);
        // 停止定时器
        executor.shutdown();
    }

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值