Backo { public long backoff(int attempt) { long duration = base * (long) Math.pow(factor, attempt); if (jitter != 0) { double random = Math.random(); int deviation = (int) Math.floor(random * jitter * duration); if ((((int) Math.floor(random * 10)) & 1) == 0) { duration = duration - deviation; } else { duration = duration + deviation; } } if (duration < 0) { duration = Long.MAX_VALUE; } return Math.min(Math.max(duration, base), cap); } private  Backo(long base, int factor, double jitter, long cap); static Builder builder(); void sleep(int attempt); long backoff(int attempt);  }
@Test public void backoff() { Backo backo = new Backo.Builder().build(); assertThat(backo.backoff(0)).isEqualTo(100); assertThat(backo.backoff(1)).isEqualTo(200); assertThat(backo.backoff(2)).isEqualTo(400); assertThat(backo.backoff(3)).isEqualTo(800); assertThat(backo.backoff(0)).isEqualTo(100); assertThat(backo.backoff(1)).isEqualTo(200); }