2017-08-03 23 views
13

Jaka jest różnica między CompletableFuture.get() i() CompletableFuture.joincompletablefuture dołączyć vs dostać

Poniżej jest mój kod:

List<String> process() { 

    List<String> messages = Arrays.asList("Msg1", "Msg2", "Msg3", "Msg4", "Msg5", "Msg6", "Msg7", "Msg8", "Msg9", 
      "Msg10", "Msg11", "Msg12"); 
    MessageService messageService = new MessageService(); 
    ExecutorService executor = Executors.newFixedThreadPool(4); 

    List<String> mapResult = new ArrayList<>(); 

    CompletableFuture<?>[] fanoutRequestList = new CompletableFuture[messages.size()]; 
    int count = 0; 
    for (String msg : messages) { 
     CompletableFuture<?> future = CompletableFuture 
       .supplyAsync(() -> messageService.sendNotification(msg), executor).exceptionally(ex -> "Error") 
       .thenAccept(mapResult::add); 

     fanoutRequestList[count++] = future; 
    } 

    try { 
     CompletableFuture.allOf(fanoutRequestList).get(); 
     //CompletableFuture.allOf(fanoutRequestList).join(); 
    } catch (InterruptedException | ExecutionException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    return mapResult.stream().filter(s -> !s.equalsIgnoreCase("Error")).collect(Collectors.toList()); 
} 

Próbowałem z obu metod, ale nie ma różnicy w wynik.

Dzięki

+4

'get()' wymaga, złapać sprawdzone wyjątki. Po zmianie z 'get()' na 'join()', zauważysz różnicę, ponieważ natychmiast dostaniesz błąd kompilatora mówiąc, że ani 'InterruptedException' ani' ExecutionException' nie są zgłaszane w bloku 'try'. – Holger

+1

@ holi-java: 'join()' nie może zostać przerwane. – Holger

+0

@ Hger tak, proszę pana. Stwierdziłem, że nie mogę przerwać zadania. –

Odpowiedz

7

jedyną różnicą jest to, w jaki sposób metody generują wyjątki. get() jest zadeklarowana w Future interfejsu jako

V get() throws InterruptedException, ExecutionException; 

Wyjątkami są zarówno sprawdzone wyjątki co oznacza muszą być obsługiwane w kodzie. Jak widzisz w swoim kodzie, automatyczny generator kodu w twoim IDE zapytał, czy utworzyć blok try-catch w twoim imieniu.

try { 
    CompletableFuture.allOf(fanoutRequestList).get() 
} catch (InterruptedException | ExecutionException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} 

Sposób join() nie rzucać sprawdzone wyjątki.

public T join() 

Zamiast tego rzuca niezaznaczone CompletionException. Więc nie trzeba blok try-catch a zamiast tego można w pełni wykorzystać exceptionally() metodę podczas korzystania z disscused List<String> process funkcję

CompletableFuture<List<String>> cf = CompletableFuture 
    .supplyAsync(this::process) 
    .exceptionally(this::getFallbackListOfStrings) // Here you can catch e.g. {@code join}'s CompletionException 
    .thenAccept(this::processFurther); 

Można znaleźć zarówno realizację get() i join()here