类 RateLimiter

java.lang.Object
ai.nextbillion.maps.internal.ratelimiter.RateLimiter

public abstract class RateLimiter
extends java.lang.Object
A rate limiter. Conceptually, a rate limiter distributes permits at a configurable rate. Each acquire() blocks if necessary until a permit is available, and then takes it. Once acquired, permits need not be released.

Rate limiters are often used to restrict the rate at which some physical or logical resource is accessed. This is in contrast to Semaphore 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.

Note: RateLimiter does not provide fairness guarantees.

从以下版本开始:
13.0
作者:
Dimitris Andreou
  • 方法概要

    修饰符和类型 方法 说明
    double acquire()
    Acquires a single permit from this RateLimiter, blocking until the request can be granted.
    double acquire​(int permits)
    Acquires the given number of permits from this RateLimiter, blocking until the request can be granted.
    static RateLimiter create​(double permitsPerSecond)  
    static RateLimiter create​(double permitsPerSecond, long warmupPeriod, java.util.concurrent.TimeUnit unit)  
    double getRate()  
    void setRate​(double permitsPerSecond)
    Updates the stable rate of this RateLimiter, that is, the permitsPerSecond argument provided in the factory method that constructed the RateLimiter.
    java.lang.String toString()  
    boolean tryAcquire()
    Acquires a permit from this RateLimiter if it can be acquired immediately without delay.
    boolean tryAcquire​(int permits)
    Acquires permits from this RateLimiter if it can be acquired immediately without delay.
    boolean tryAcquire​(int permits, long timeout, java.util.concurrent.TimeUnit unit)
    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.
    boolean tryAcquire​(long timeout, java.util.concurrent.TimeUnit unit)
    Acquires a permit from this RateLimiter if it can be obtained without exceeding the specified timeout, or returns false immediately (without waiting) if the permit would not have been granted before the timeout expired.

    从类继承的方法 java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
  • 方法详细资料

    • create

      public static RateLimiter create​(double permitsPerSecond)
    • create

      public static RateLimiter create​(double permitsPerSecond, long warmupPeriod, java.util.concurrent.TimeUnit unit)
    • setRate

      public final void setRate​(double permitsPerSecond)
      Updates the stable rate of this RateLimiter, that is, the permitsPerSecond argument provided in the factory method that constructed the RateLimiter. Currently throttled threads will not be awakened as a result of this invocation, thus they do not observe the new rate; only subsequent requests will.

      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 setRate will not be affected by the new rate; it will pay the cost of the previous request, which is in terms of the previous rate.

      The behavior of the RateLimiter is not modified in any other way, e.g. if the RateLimiter was configured with a warmup period of 20 seconds, it still has a warmup period of 20 seconds after this method invocation.

      参数:
      permitsPerSecond - the new stable rate of this RateLimiter
      抛出:
      java.lang.IllegalArgumentException - if permitsPerSecond is negative or zero
    • getRate

      public final double getRate()
    • acquire

      public double acquire()
      Acquires a single permit from this RateLimiter, blocking until the request can be granted. Tells the amount of time slept, if any.

      This method is equivalent to acquire(1).

      返回:
      time spent sleeping to enforce rate, in seconds; 0.0 if not rate-limited
      从以下版本开始:
      16.0 (present in 13.0 with void return type})
    • acquire

      public double acquire​(int permits)
      Acquires the given number of permits from this RateLimiter, blocking until the request can be granted. Tells the amount of time slept, if any.
      参数:
      permits - the number of permits to acquire
      返回:
      time spent sleeping to enforce rate, in seconds; 0.0 if not rate-limited
      抛出:
      java.lang.IllegalArgumentException - if the requested number of permits is negative or zero
      从以下版本开始:
      16.0 (present in 13.0 with void return type})
    • tryAcquire

      public boolean tryAcquire​(long timeout, java.util.concurrent.TimeUnit unit)
      Acquires a permit from this RateLimiter if it can be obtained without exceeding the specified timeout, or returns false immediately (without waiting) if the permit would not have been granted before the timeout expired.

      This method is equivalent to tryAcquire(1, timeout, unit).

      参数:
      timeout - the maximum time to wait for the permit. Negative values are treated as zero.
      unit - the time unit of the timeout argument
      返回:
      true if the permit was acquired, false otherwise
      抛出:
      java.lang.IllegalArgumentException - if the requested number of permits is negative or zero
    • tryAcquire

      public boolean tryAcquire​(int permits)
      Acquires permits from this RateLimiter if it can be acquired immediately without delay.

      This method is equivalent to tryAcquire(permits, 0, anyUnit).

      参数:
      permits - the number of permits to acquire
      返回:
      true if the permits were acquired, false otherwise
      抛出:
      java.lang.IllegalArgumentException - if the requested number of permits is negative or zero
      从以下版本开始:
      14.0
    • tryAcquire

      public boolean tryAcquire()
      Acquires a permit from this RateLimiter if it can be acquired immediately without delay.

      This method is equivalent to tryAcquire(1).

      返回:
      true if the permit was acquired, false otherwise
      从以下版本开始:
      14.0
    • tryAcquire

      public boolean tryAcquire​(int permits, long timeout, java.util.concurrent.TimeUnit unit)
      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.
      参数:
      permits - the number of permits to acquire
      timeout - the maximum time to wait for the permits. Negative values are treated as zero.
      unit - the time unit of the timeout argument
      返回:
      true if the permits were acquired, false otherwise
      抛出:
      java.lang.IllegalArgumentException - if the requested number of permits is negative or zero
    • toString

      public java.lang.String toString()
      覆盖:
      toString 在类中 java.lang.Object