Gram z kompletnymi kontraktami Java 8. Mam następujący kod:Jak anulować kompletną przyszłość Java 8?
CountDownLatch waitLatch = new CountDownLatch(1);
CompletableFuture<?> future = CompletableFuture.runAsync(() -> {
try {
System.out.println("Wait");
waitLatch.await(); //cancel should interrupt
System.out.println("Done");
} catch (InterruptedException e) {
System.out.println("Interrupted");
throw new RuntimeException(e);
}
});
sleep(10); //give it some time to start (ugly, but works)
future.cancel(true);
System.out.println("Cancel called");
assertTrue(future.isCancelled());
assertTrue(future.isDone());
sleep(100); //give it some time to finish
Użycie runAsync Planuję wykonanie kodu, który czeka na zatrzask. Następnie anuluję przyszłość, oczekując, że przerwany wyjątek zostanie wrzucony do środka. Wygląda jednak na to, że wątek pozostaje zablokowany w oczekiwaniu na połączenie, a wyjątek InterruptedException nigdy nie zostanie zgłoszony, nawet jeśli przyszłość zostanie anulowana (asercje mijają). Odpowiedni kod przy użyciu ExecutorService działa zgodnie z oczekiwaniami. Czy jest to błąd w programie CompletableFuture lub w moim przykładzie?
Czy możesz odtworzyć problem za pomocą 'Executors.newFixedThreadPool' kontra' Executors.newWorkStealingPool'? Sprawiłoby to, że pytanie byłoby bardziej przejrzyste, gdyby porównać dwie różne implementacje wykonawców niż porównywać kontrakty terminowe z kontraktami futures. – nosid
JavaDoc mówi, że anulowanie (true) jest anulowane z wyjątkiem CancellationException, ale nie łapiesz tego. – edharned
@nosid Masz rację, newWorkStealingPool podobno nie obsługuje anulowania ani – Lukas