code: public final void setRate(double permitsPerSecond) {
      Preconditions.checkArgument(permitsPerSecond > 0.0
          && !Double.isNaN(permitsPerSecond), "rate must be positive");
      resync(readSafeMicros());
      double stableIntervalMicros = TimeUnit.SECONDS.toMicros(1L) / permitsPerSecond;
      this.stableIntervalMicros = stableIntervalMicros;
      doSetRate(permitsPerSecond, stableIntervalMicros);
    }
docs: Updates the stable rate of this {@code UnsynchronizedRateLimiter}, that is, the
  {@code permitsPerSecond} argument provided in the factory method that
  constructed the {@code UnsynchronizedRateLimiter}. Currently throttled threads will <b>not</b>
  be awakened as a result of this invocation, thus they do not observe the new rate;
  only subsequent requests will.
  
  <p>Note though that, since each request repays (by waiting, if necessary) the cost
  of the <i>previous</i> request, this means that the very next request
  after an invocation to {@code 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.
  
  <p>The behavior of the {@code UnsynchronizedRateLimiter} is not modified in any other way,
  e.g. if the {@code UnsynchronizedRateLimiter} was configured with a warmup period of 20 seconds,
  it still has a warmup period of 20 seconds after this method invocation.
  
  @param permitsPerSecond the new stable rate of this {@code UnsynchronizedRateLimiter}. Must be positive