Lazy refill under a lock
Time O(1) Space O(1)tokens = min(capacity, tokens + (t − last) × rate); last = t; if tokens ≥ 1, spend one.
capacity 2, refill 1: allow(0), allow(0), allow(0), allow(1)state(vars)
returned(list)
empty
Step 1/4The bucket starts full with 2 tokens.
class TokenBucket {
private final long capacity, rate;
private long tokens, last;
public TokenBucket(int capacity, int refillPerSecond) {
this.capacity = capacity;
this.rate = refillPerSecond;
this.tokens = capacity;
this.last = 0;
}
public synchronized boolean allow(int timestamp) {
tokens = Math.min(capacity, tokens + (timestamp - last) * rate);
last = timestamp;
if (tokens == 0) return false;
tokens--;
return true;
}
}Verdict: The algorithm behind many API gateways.