Вы не должны помещать рабочий поток исполнителя в sleep
.
Одним из решений для планирования новой попытки будет
Executor executor; // … the actual executor
ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
Executor afterTenSeconds
= r -> ses.schedule(() -> executor.execute(r), 10, TimeUnit.SECONDS);
Runnable primaryAction
= () -> dndService.initateDNDRequest(transactionId, circle, category, "PREPAID");
CompletableFuture<Void> cf = CompletableFuture.runAsync(primaryAction, executor);
for(int i = 0; i < 3; i++) {
cf = cf.handle((v,t) -> t == null? CompletableFuture.completedFuture(v):
CompletableFuture.runAsync(primaryAction, afterTenSeconds))
.thenCompose(Function.identity());
}
Тогда действие handle
запланирует новоепопытка, которая будет выполнена после тайм-аута (десять секунд) в случае сбоя.thenCompose(Function.identity())
необходим, так как нет единого метода для объединения семантики handle
и compose
.
Обратите внимание, что начиная с Java 9, вы можете создать отложенного исполнителя так же просто, как
Executor afterTenSeconds = CompletableFuture.delayedExecutor(10,TimeUnit.SECONDS,executor);
без необходимости иметь дело с ScheduledExecutorService
самостоятельно.