acquire() blocks if necessary until a permit is available, and then takes it. Once
acquired, permits need not be released.
RateLimiter is safe for concurrent use: It will restrict the total rate of calls from
all threads. Note, however, that it does not guarantee fairness.
Rate limiters are often used to restrict the rate at which some physical or logical resource
is accessed. This is in contrast to java. which restricts the
number of concurrent accesses instead of the rate (note though that concurrency and rate are
closely related, e.g. see Little's
Law).
A RateLimiter is defined primarily by the rate at which permits are issued. Absent
additional configuration, permits will be distributed at a fixed rate, defined in terms of
permits per second. Permits will be distributed smoothly, with the delay between individual
permits being adjusted to ensure that the configured rate is maintained.
It is possible to configure a RateLimiter to have a warmup period during which time
the permits issued each second steadily increases until it hits the stable rate.
As an example, imagine that we have a list of tasks to execute, but we don't want to submit more than 2 per second:
final RateLimiter rateLimiter = RateLimiter.create(2.0); // rate is "2 permits per second"
void submitTasks(List<Runnable> tasks, Executor executor) {
for (Runnable task : tasks) {
rateLimiter.acquire(); // may wait
executor.execute(task);
}
}
As another example, imagine that we produce a stream of data, and we want to cap it at 5kb per second. This could be accomplished by requiring a permit per byte, and specifying a rate of 5000 permits per second:
final RateLimiter rateLimiter = RateLimiter.create(5000.0); // rate = 5000 permits per second
void submitPacket(byte[] packet) {
rateLimiter.acquire(packet.length);
networkService.send(packet);
}
It is important to note that the number of permits requested never affects the
throttling of the request itself (an invocation to acquire(1) and an invocation to acquire(1000) will result in exactly the same throttling, if any), but it affects the throttling
of the next request. I.e., if an expensive task arrives at an idle RateLimiter, it will be
granted immediately, but it is the next request that will experience extra throttling,
thus paying for the cost of the expensive task.
| Modifier and Type | Class and Description |
|---|---|
| pack-priv abstract static class |
| Modifier and Type | Field and Description |
|---|---|
| private volatile Object | |
| private final RateLimiter. | stopwatch
The underlying timer; used both to measure elapsed time and sleep as necessary. |
| Access | Constructor and Description |
|---|---|
| pack-priv |
| Modifier and Type | Method and Description |
|---|---|
| public double | Returns: time spent sleeping to enforce rate, in seconds; 0.0 if not rate-limitedAcquires a single permit from this |
| public double | Returns: time spent sleeping to enforce rate, in seconds; 0.0 if not rate-limitedthe number of permits to acquire permits)Acquires the given number of permits from this |
| private boolean | |
| private static void | |
| public static RateLimiter | create(double
the rate of the returned permitsPerSecond)RateLimiter, measured in how many
permits become available per secondCreates a |
| pack-priv static RateLimiter | |
| public static RateLimiter | create(double
the rate of the returned permitsPerSecond, Duration RateLimiter, measured in how many
permits become available per secondthe duration of the period where the warmupPeriod)RateLimiter ramps up its rate,
before reaching its stable (maximum) rateCreates a |
| public static RateLimiter | create(double
the rate of the returned permitsPerSecond, long RateLimiter, measured in how many
permits become available per secondthe duration of the period where the warmupPeriod, TimeUnit RateLimiter ramps up its rate,
before reaching its stable (maximum) ratethe time unit of the warmupPeriod argument unit)Creates a |
| pack-priv static RateLimiter | create(double permitsPerSecond, long warmupPeriod, TimeUnit unit, double coldFactor, RateLimiter.
|
| pack-priv abstract double | |
| pack-priv abstract void | |
| public final double | getRate()
Returns the stable rate (as |
| private Object | |
| pack-priv abstract long | Returns: the time that permits are available, or, if permits are available immediately, an arbitrary past or present timeReturns the earliest time that permits are available (with one caveat). |
| pack-priv final long | Returns: time in microseconds to wait until the resource can be acquired, never negativeReserves the given number of permits from this |
| pack-priv final long | Returns: the required wait time, never negativeReserves next ticket and returns the wait time that the caller must wait for. |
| pack-priv abstract long | Returns: the time that the permits may be used, or, if the permits may be used immediately, an arbitrary past or present timeReserves the requested number of permits and returns the time that those permits can be used (with one caveat). |
| public final void | setRate(double
the new stable rate of this permitsPerSecond)RateLimiterUpdates the stable rate of this |
| public String | |
| public boolean | Returns: true if the permit was acquired, false otherwisethe maximum time to wait for the permit. Negative values are treated as zero. timeout)Acquires a permit from this |
| public boolean | Returns: true if the permit was acquired, false otherwisethe maximum time to wait for the permit. Negative values are treated as zero. timeout, TimeUnit the time unit of the timeout argument unit)Acquires a permit from this |
| public boolean | Returns: true if the permits were acquired, false otherwisethe number of permits to acquire permits)Acquires permits from this |
| public boolean | Returns: true if the permit was acquired, false otherwiseAcquires a permit from this |
| public boolean | Returns: true if the permits were acquired, false otherwisethe number of permits to acquire permits, Duration the maximum time to wait for the permits. Negative values are treated as zero. timeout)Acquires the given number of permits from this |
| public boolean | Returns: true if the permits were acquired, false otherwisethe number of permits to acquire permits, long the maximum time to wait for the permits. Negative values are treated as zero. timeout, TimeUnit the time unit of the timeout argument unit)Acquires the given number of permits from this |
| mutexDoNotUseDirectly | back to summary |
|---|---|
| private volatile Object mutexDoNotUseDirectly
| |
| stopwatch | back to summary |
|---|---|
| private final RateLimiter. The underlying timer; used both to measure elapsed time and sleep as necessary. A separate object to facilitate testing. | |
| RateLimiter | back to summary |
|---|---|
| pack-priv RateLimiter(RateLimiter. | |
| acquire | back to summary |
|---|---|
| public double acquire() Acquires a single permit from this This method is equivalent to
| |
| acquire | back to summary |
|---|---|
| public double acquire(int permits) Acquires the given number of permits from this
| |
| canAcquire | back to summary |
|---|---|
| private boolean canAcquire(long nowMicros, long timeoutMicros) | |
| checkPermits | back to summary |
|---|---|
| private static void checkPermits(int permits) | |
| create | back to summary |
|---|---|
| public static RateLimiter create(double permitsPerSecond) Creates a The returned
| |
| create | back to summary |
|---|---|
pack-priv static RateLimiter create(double permitsPerSecond, RateLimiter.
| |
| create | back to summary |
|---|---|
| public static RateLimiter create(double permitsPerSecond, Duration warmupPeriod) Creates a The returned The returned
| |
| create | back to summary |
|---|---|
| public static RateLimiter create(double permitsPerSecond, long warmupPeriod, TimeUnit unit) Creates a The returned The returned
| |
| create | back to summary |
|---|---|
pack-priv static RateLimiter create(double permitsPerSecond, long warmupPeriod, TimeUnit unit, double coldFactor, RateLimiter.
| |
| doGetRate | back to summary |
|---|---|
| pack-priv abstract double doGetRate() | |
| doSetRate | back to summary |
|---|---|
| pack-priv abstract void doSetRate(double permitsPerSecond, long nowMicros) | |
| getRate | back to summary |
|---|---|
| public final double getRate() Returns the stable rate (as | |
| mutex | back to summary |
|---|---|
| private Object mutex() | |
| queryEarliestAvailable | back to summary |
|---|---|
| pack-priv abstract long queryEarliestAvailable(long nowMicros) Returns the earliest time that permits are available (with one caveat).
| |
| reserve | back to summary |
|---|---|
| pack-priv final long reserve(int permits) Reserves the given number of permits from this
| |
| reserveAndGetWaitLength | back to summary |
|---|---|
| pack-priv final long reserveAndGetWaitLength(int permits, long nowMicros) Reserves next ticket and returns the wait time that the caller must wait for.
| |
| reserveEarliestAvailable | back to summary |
|---|---|
| pack-priv abstract long reserveEarliestAvailable(int permits, long nowMicros) Reserves the requested number of permits and returns the time that those permits can be used (with one caveat).
| |
| setRate | back to summary |
|---|---|
| public final void setRate(double permitsPerSecond) Updates the stable rate of this Note though that, since each request repays (by waiting, if necessary) the cost of the
previous request, this means that the very next request after an invocation to The behavior of the
| |
| toString | back to summary |
|---|---|
| public String toString() Overrides java. Doc from java. Returns a string representation of the object. | |
| tryAcquire | back to summary |
|---|---|
| public boolean tryAcquire(Duration timeout) Acquires a permit from this This method is equivalent to
| |
| tryAcquire | back to summary |
|---|---|
| public boolean tryAcquire(long timeout, TimeUnit unit) Acquires a permit from this This method is equivalent to
| |
| tryAcquire | back to summary |
|---|---|
| public boolean tryAcquire(int permits) Acquires permits from this This method is equivalent to
| |
| tryAcquire | back to summary |
|---|---|
| public boolean tryAcquire() Acquires a permit from this This method is equivalent to
| |
| tryAcquire | back to summary |
|---|---|
| public boolean tryAcquire(int permits, Duration timeout) Acquires the given number of permits from this
| |
| tryAcquire | back to summary |
|---|---|
| public boolean tryAcquire(int permits, long timeout, TimeUnit unit) Acquires the given number of permits from this
| |
| Access | Constructor and Description |
|---|---|
| protected |
| Modifier and Type | Method and Description |
|---|---|
| public static RateLimiter. | |
| protected abstract long | |
| protected abstract void |
| SleepingStopwatch | back to summary |
|---|---|
| protected SleepingStopwatch() Constructor for use by subclasses. | |
| createFromSystemTimer | back to summary |
|---|---|
| public static RateLimiter. | |
| readMicros | back to summary |
|---|---|
| protected abstract long readMicros() | |
| sleepMicrosUninterruptibly | back to summary |
|---|---|
| protected abstract void sleepMicrosUninterruptibly(long micros) | |