N'utilisez pas join()
si vous souhaitez prendre en charge l'interruption, utilisez plutôt get()
. ils sont fondamentalement les mêmes, sauf:
join()
provient de l'interface CompletionStage
alors que get()
vient interface sous forme Future
join()
enveloppements exceptions CompletionException
alors que get()
les enveloppe dans ExecutionException
get()
pourrait être interrompu et aurait alors jeter un InterruptedException
Notez que ce que vous interrompez est le Thread
, pas le Future
. Par exemple, le code suivant interrompt le thread principal alors qu'il est en attente sur myFuture.get()
:
CompletableFuture<Void> myFuture = new CompletableFuture<>();
Thread mainThread = Thread.currentThread();
CompletableFuture.runAsync(() -> {
try {
Thread.sleep(1000);
System.out.println("Interrupting…");
mainThread.interrupt();
Thread.sleep(1000);
System.out.println("Completing");
myFuture.complete(null);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
try {
myFuture.get();
System.out.println("Get succeeded");
} catch (Exception e) {
System.out.println("Get failed");
e.printStackTrace();
}
Sortie:
Interrupting…
Get failed
java.lang.InterruptedException
at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:347)
at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1895)
at CompletableFutureInteruption.main(CompletableFutureInteruption.java:37)
…
Si vous remplacez get()
par join()
, l'interruption sera en effet pas fonctionner.
Je me demande si c'est ce que vous cherchez: https://stackoverflow.com/questions/43389894/recursively-cancel-an-alloff-completablefuture/43391133#43391133 – Eugene
@Eugene Merci pour le lien. Je sais que 'CompletableFuture :: cancel' n'interrompra pas le thread. Ce que je veux faire est d'interrompre un thread qui bloque dans une opération 'CompletableFuture :: join'. Peut-être devrais-je décrire ma question plus clairement. – phil