2017-05-12 16 views
5

W przeciwieństwie do stwierdzonych w niektórych blogach (np. I can't emphasize this enough: thenAccept()/thenRun() methods do not block) CompletableFuture.thenAccept może rzeczywiście blokować. Rozważmy następujący kod, odkomentowanie wywołanie pause metoda spowoduje thenAccept zablokować:CompletableFuture.thenAccept może rzeczywiście blokować

CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { 
    log.trace("return 42"); 
    return "42"; 
}); 

//pause(1000); //uncommenting this will cause blocking of thenAccept 

future.thenAccept((dbl -> { 
    log.trace("blocking"); 
    pause(500); 
    log.debug("Result: " + dbl); 
})); 

log.trace("end"); 
pause(1000); 

Czy możemy mieć pewność, że dodaje się nie zablokuje? Rozumiem, że jeśli supplyAsync działa natychmiast, to thenAccept może blokować, nie?

CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> { 
    return "42"; 
}).thenAccept((dbl -> { 
    pause(500); 
    log.debug("Result: " + dbl); 
})); 

Odpowiedz

6

Masz rację, thenAccept() zablokuje jeśli przyszłość jest już zakończona. Zwróć też uwagę, że gdy tak nie jest, spowoduje to, że wątek, który je zakończy, zablokuje się w momencie ukończenia.

To dlaczego masz thenAcceptAsync(), który będzie uruchomić Consumer w non-blocking sposób:

CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> { 
    return "42"; 
}).thenAcceptAsync((dbl -> { 
    pause(500); 
    log.debug("Result: " + dbl); 
})); 

Zobacz również Which executor is used when composing Java CompletableFutures?

Powiązane problemy