当前位置: 首页 > news >正文

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的超时参数,是在预期超时之前能够获取到令牌才会阻塞等待,否则会理解返回获取失败

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 自建远程桌面RustDesk服务器(CentOS配置,保姆级案例)
  • 1999-2023年上市公司年报文本数据(PDF+TXT)
  • python用波形显示udp数据实现一个模拟示波器
  • 在Ubuntu 16.04上安装MySQL的方法
  • MFC工控项目实例之九选择下拉菜单主界面文本框显示菜单名
  • Java并发编程 第四章 共享模型之管程 上
  • 数据仓库系列14:数据清洗和转换的常见方法有哪些?
  • 从地图信息实时检测路口的各向通行状况、红绿灯及溢出情况
  • 初识C++|list类的使用及模拟实现
  • Qt 调用MFC dll,动态库中有界面
  • windows C++ 并行编程-使用 Lambda 表达式
  • MYSQL数据库(四)
  • JavaScript学习文档(11):Window对象、本地存储、数组中一些方法、学生就业统计表案例
  • 15行为型设计模式——责任链模式
  • Java基础入门【第六章 static、继承、重写、多态】(二)
  • 【407天】跃迁之路——程序员高效学习方法论探索系列(实验阶段164-2018.03.19)...
  • 4月23日世界读书日 网络营销论坛推荐《正在爆发的营销革命》
  • Cumulo 的 ClojureScript 模块已经成型
  • Git 使用集
  • Javascripit类型转换比较那点事儿,双等号(==)
  • javascript面向对象之创建对象
  • JavaScript学习总结——原型
  • Perseus-BERT——业内性能极致优化的BERT训练方案
  • 搭建gitbook 和 访问权限认证
  • 服务器从安装到部署全过程(二)
  • 欢迎参加第二届中国游戏开发者大会
  • 看域名解析域名安全对SEO的影响
  • 聊聊directory traversal attack
  • 首页查询功能的一次实现过程
  • 小程序01:wepy框架整合iview webapp UI
  • 小李飞刀:SQL题目刷起来!
  • 一文看透浏览器架构
  • 通过调用文摘列表API获取文摘
  • ​Spring Boot 分片上传文件
  • ‌移动管家手机智能控制汽车系统
  • #includecmath
  • #每天一道面试题# 什么是MySQL的回表查询
  • #如何使用 Qt 5.6 在 Android 上启用 NFC
  • ${ }的特别功能
  • ()、[]、{}、(())、[[]]等各种括号的使用
  • (PWM呼吸灯)合泰开发板HT66F2390-----点灯大师
  • (附源码)node.js知识分享网站 毕业设计 202038
  • (附源码)计算机毕业设计SSM智慧停车系统
  • (未解决)macOS matplotlib 中文是方框
  • (转)memcache、redis缓存
  • (转)ORM
  • (转)scrum常见工具列表
  • .net 4.0发布后不能正常显示图片问题
  • .Net IOC框架入门之一 Unity
  • .NET设计模式(11):组合模式(Composite Pattern)
  • .Net中的设计模式——Factory Method模式
  • .sh文件怎么运行_创建优化的Go镜像文件以及踩过的坑
  • //usr/lib/libgdal.so.20:对‘sqlite3_column_table_name’未定义的引用
  • @SentinelResource详解
  • @SpringBootApplication 注解