Retry a failing call with capped backoff

Java
import java.time.Duration;
import java.util.concurrent.ThreadLocalRandom;
import java.util.function.Supplier;

/** Retries a flaky supplier with exponential backoff, jitter and a cap. */
public final class Retry {
    private Retry() {
    }

    public static <T> T call(Supplier<T> action, int maxAttempts, Duration baseDelay)
            throws InterruptedException {
        RuntimeException last = null;
        for (int attempt = 1; attempt <= maxAttempts; attempt++) {
            try {
                return action.get();
            } catch (RuntimeException e) {
                last = e;
                if (attempt == maxAttempts) {
                    break;
                }
                long backoff = Math.min(baseDelay.toMillis() << Math.min(attempt - 1, 10), 10_000L);
                long jitter = ThreadLocalRandom.current().nextLong(0, backoff / 2 + 1);
                Thread.sleep(backoff / 2 + jitter);
            }
        }
        throw new IllegalStateException("all " + maxAttempts + " attempts failed", last);
    }

    public static void main(String[] args) throws InterruptedException {
        int[] calls = {0};
        String result = call(() -> {
            if (calls[0]++ < 2) {
                throw new IllegalStateException("transient error");
            }
            return "ok after " + calls[0] + " calls";
        }, 5, Duration.ofMillis(50));
        System.out.println(result); // ok after 3 calls
    }
}