RateLimiter是Google Guava框架的一个限速器,通常用于控制对某个资源的访问速率。
限速常见的有两种实现方式,一种是令牌桶,另一种是漏桶。
RateLimiter选择了令牌桶作为其底层实现,按照固定速率投放令牌,同时支持突发流量。
本篇先来解读一下Ticker和Stopwatch,它们是RateLimiter底层时间计算的基础。
代码基于Guava 23.0版本。
Ticker
Ticker的意思钟表,里面只有一个read()方法,用来获取当前时间。
核心代码解读:
public abstract class Ticker {
// 获取当前时间
public abstract long read();
// Ticker默认实现. read()内部实际是调用java.lang.System.nanoTime()方法
private static final Ticker SYSTEM_TICKER =
new Ticker() {
@Override
public long read() {
return Platform.systemNanoTime();
}
};
}
Stopwatch
Stopwatch是一个计时器,也叫秒表。通常用于测量程序功能的运行时长。
功能和实际的物理秒表非常相似,现在手机一般都会有秒表功能,大家可以先用手机感受一下,然后再去理解该类就会比较简单了。
秒表通常会支持开始、停止和重置。可以将多次开始和结束之间的时间进行累计,支持重置秒表后重新开始。没错,Stopwatch就实现了这个最基本的功能。
核心代码解读:
public final class Stopwatch {
/**
* 钟表. 主要用于获取当前的纳秒数,默认使用System.nanoTime().
*/
private final Ticker ticker;
/**
* 秒表的运行状态.<br>
* 调用start()时设置为true,表示运行中,开始计时.<br>
* 调用stop()、reset()时设置为false,表示停止,结束本次计时.
*/
private boolean isRunning;
/**
* 秒表总的计时时长.<br>
* 计算规则:每执行一次"start() 到 stop()"之间经过的时间之和。从"stop() 到 start()"之间的时间不做累计.<br>
* 更新时机:仅在执行stop()和reset()时更新.
*/
private long elapsedNanos;
/**
* 秒表开始计时的时间. 每次调用start()时更新为当前时间,进行下一轮的计时.
*/
private long startTick;
/**
* 默认构造函数. 使用默认的Ticker
*/
Stopwatch(