long (long effectiveDelayMs, long backoffLimitMs) { try { Thread.sleep(effectiveDelayMs); } catch (InterruptedException ex) { Thread.currentThread().interrupt(); throw new RuntimeException("Unexpected thread interrupt", ex); } long nextRawDelay = (long)Math.min(effectiveDelayMs * EXP_BACKOFF_FACTOR, backoffLimitMs); long jitter = (long)(RANDOM.nextDouble() * nextRawDelay * EXP_BACKOFF_JITTER); long jitterSign = RANDOM.nextBoolean() ? 1 : -1; return nextRawDelay + jitter * jitterSign; }