code: public synchronized void throttle() throws InterruptedException
      {
          // Get the current time in nanos.
          long currentTimeNanos = System.nanoTime();
  
          // Don't introduce any pause on the first call.
          if (!firstCall)
          {
              // Check if there is any time left in the cycle since the last call to this method and introduce a short pause
              // to fill that time if there is.
              long remainingTimeNanos = cycleTimeNanos - (currentTimeNanos - lastTimeNanos);
  
              if (remainingTimeNanos > 0)
              {
                  long milliPause = remainingTimeNanos / 1000000;
                  int nanoPause = (int) (remainingTimeNanos % 1000000);
  
                  Thread.sleep(milliPause, nanoPause);
              }
          }
          else
          {
              firstCall = false;
          }
  
          // Update the last time stamp.
          lastTimeNanos = System.nanoTime();
      }
docs: This method can only be called at the rate set by the {@link #setRate} method, if it is called faster than this
  it will inject short pauses to restrict the call rate to that rate.
  
  @throws InterruptedException If interrupted whilst performing a blocking wait on the throttle.