RateLimiter超时

案例

public static void main(String[] args) {
    // 创建一个RateLimiter,速率为每秒1个许可
    RateLimiter rateLimiter = RateLimiter.create(1.0);

    // 预先消耗所有的初始许可
    rateLimiter.acquire(1);

    // 创建并启动多个线程来模拟高并发
    for (int i = 0; i < 5; i++) {
        final int threadNumber = i;
        new Thread(() -> {
            long start = System.currentTimeMillis();
            boolean acquired = rateLimiter.tryAcquire(1, 1000, TimeUnit.MILLISECONDS);
            long end = System.currentTimeMillis();
            long diff = end - start;
            if (acquired) {
                System.out.println("Thread " + threadNumber + " acquired permit: " + diff + " ms");
            } else {
                System.out.println("Thread " + threadNumber + " could not acquire permit (timeout): " + diff + " ms");
            }
        }).start();
    }
}

输出结果

Thread 4 could not acquire permit (timeout): 0 ms
Thread 1 could not acquire permit (timeout): 0 ms
Thread 2 could not acquire permit (timeout): 0 ms
Thread 3 could not acquire permit (timeout): 0 ms
Thread 0 acquired permit: 999 ms

解释

官方注解

Acquires the given number of permits from this RateLimiter if it can be obtained without exceeding the specified timeout, or returns false immediately (without waiting) if the permits would not have been granted before the timeout expired.
获取指定数量的许可,如果可以在不超过指定超时时间的情况下获得许可,否则立即返回 false(不等待),如果许可在超时之前不能被授予。

在单线程示例中,每次调用大约等待一秒钟就能获得许可,因此不会抛出任何异常。这是你的代码中发生的情况:

  1. 第一次调用知道可以立即获得许可,所以它立即获得许可。
  2. 在第一次调用完成后,第二次调用知道如果等待大约 1 秒钟可以获得许可,所以它等待大约 1 秒并获得许可。
  3. 在第二次调用完成后,第三次调用知道如果等待大约 1 秒钟可以获得许可,所以它等待大约 1 秒并获得许可。
  4. 在第三次调用完成后,第四次调用知道如果等待大约 1 秒钟可以获得许可,所以它等待大约 1 秒并获得许可。
  5. 程序结束。

现在,尝试在多线程示例中使用这个,你将开始看到一些失败和一些成功。因为它们都想同时获得许可。

  1. 第一个获得许可的线程很高兴。
  2. 然后第二个线程知道如果等待大约 1 秒钟,它可以获得许可,所以它等待直到获得许可。
  3. 第三个和第四个线程看到队列中已经有两个调用,知道它们必须等待 2 秒钟才能获得许可。所以它们放弃了,因为你设置的 1 秒超时已经超过了 2 秒。

在这个多线程示例中,你会看到多个线程同时尝试获取许可时,会出现一些线程成功获取许可,而其他线程因超时而失败。

总结

  1. tryAcquire的超时参数,是在预期超时之前能够获取到令牌才会阻塞等待,否则会理解返回获取失败
  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值