BoundedExponentialBackoffRetryUntilElapsed implements RetryPolicy { @Override public boolean allowRetry(int retryCount, long elapsedTimeMs, RetrySleeper sleeper) { if (elapsedTimeMs >= maxElapsedTimeMs) { return false; } long sleepTimeMs = Math.min(maxElapsedTimeMs - elapsedTimeMs, getSleepTimeMs(retryCount, elapsedTimeMs)); try { sleeper.sleepFor(sleepTimeMs, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { Thread.currentThread().interrupt(); return false; } return true; } BoundedExponentialBackoffRetryUntilElapsed(int baseSleepTimeMs, int maxSleepTimeMs,
            long maxElapsedTimeMs); @Override boolean allowRetry(int retryCount, long elapsedTimeMs, RetrySleeper sleeper);  }
@Test public void test() { FakeRetrySleeper sleeper = new FakeRetrySleeper(); BoundedExponentialBackoffRetryUntilElapsed r = new BoundedExponentialBackoffRetryUntilElapsed( 10, 2000, 60000); for (int i = 0; i < 100; i++) { assertTrue(r.allowRetry(i, ThreadLocalRandom.current().nextInt(60000), sleeper)); System.out.println(sleeper.sleepTimeMs); assertTrue(sleeper.sleepTimeMs <= 2000); } assertTrue(r.allowRetry(1000, 59900, sleeper)); System.out.println(sleeper.sleepTimeMs); assertTrue(sleeper.sleepTimeMs <= 100); sleeper.sleepTimeMs = -1L; assertFalse(r.allowRetry(1, 60000, sleeper)); assertEquals(-1L, sleeper.sleepTimeMs); }