2014-04-20 3 views
10

Die übliche Methode, um mit disruptedException umzugehen, ist entweder erneut zu unterbrechen oder direct throw disruptedException, aber beide können nicht funktionieren. Jeder hat die Idee?JDK8 CompletableFuture.supplyAsync wie mit disruptedException umzugehen ist

+0

"* aber beide können nicht funktionieren. *" => Warum? – assylias

+0

beide haben Compilerfehler. Wenn der Direct-Throw-Ausnahmefehler auftritt, zeigt der Compiler unbehandelte Exception an, wenn catch it und Thead.current.interrupt aufrufen, der Compiler zeigt einen T-Typ zurück. – GrapeBaBa

+0

Ja, Sie müssen zurückkehren oder werfen. Wenn Sie sich dafür entscheiden, null zurückzugeben, zum Beispiel: 'try {return queue.take(); } catch (InterruptedException e) {Thread.currentThread(). interrupt(); null zurückgeben; } ' – assylias

Antwort

10

Ich ändere den Code so.

CompletableFuture<Rep> result = new CompletableFuture<>(); 
    CompletableFuture.runAsync(() -> { 

     transporter.write(req); 
     try { 
      Rep rep = responseQueue.take(); 
      result.complete(rep); 
     } catch (InterruptedException e) { 
      result.completeExceptionally(e); 
      Thread.currentThread().interrupt(); 
     } catch (Exception e) { 
      result.completeExceptionally(e); 
     } 

    }, executorService); 
    return result; 
+0

Was Sie getan haben, entspricht meinem. Leider kann 'CompletetFuture result' durch eine beliebige Klasse ersetzt werden, die dem" result or exception "-Paradigma entspricht. Zum Beispiel können Sie die Methoden 'get',' complete' und 'completeExceptional' zu' ResultWrapper' hinzufügen und 'ResultWrapper rep = new ResultWrapper();' verwenden. Es ist ein Zufall, dass Sie diese Einschränkung der Lambda-Funktion mit 'CompletableFuture' angetroffen haben und wieder mit' CompleableFuture' gelöst haben, indem Sie die von Ihnen verwendeten Methoden verwendet haben. – mostruash

+1

Ja, aber completablefuture hat bereits die Abstraktion für ein Berechnungsergebnis, also möchte ich keinen neuen Typ für dasselbe erstellen. – GrapeBaBa

+0

Wenn Sie mit anderen Personen arbeiten, kann dies die Leser Ihres Codes verwirren. Wenn nicht, großartig, dass es für dich funktioniert hat. – mostruash

3

Da Lambda-Funktionen keine Ausnahmen unterstützen, denke ich, dass Java-Entwickler ein neues Paradigma brauchen werden. Eine Sache, die in den Sinn kommt, ist wie folgt:

Lambda-Funktionen können Instanzen dieses Wrappers zurückgeben. (Edit: Ihr Fall)

CompletableFuture<ResultWrapper<String, InterruptedException>> aFuture = ...; 
... 
aFuture.supplyAsync(
() -> { 
    try { 
     transporter.write(req); 
    } catch(InterruptedException e) { 
     ResultWrapper<String, InterruptedException> r = new ResultWrapper<>(); 
     r.exception = e; 
     r.result = null; 
     return r; 
    } 
    ... 
}, executorService); 
+0

Scheint eine Lösung – GrapeBaBa

+0

Bitte markieren Sie es als Antwort, wenn Sie denken, dass es Ihnen geholfen hat :) – mostruash

+0

Anstatt Ausnahmen zu einem Rückgabewert zu konvertieren, sollten Sie sie in eine ungeprüfte Ausnahme umbrechen und sie zurück in eine geprüfte Ausnahme auf der Außenseite übersetzen. Behalten Sie Ausnahmen als Ausnahmen den ganzen Weg hindurch. Rückgabewerte sind für Nicht-Fehler-Bedingungen reserviert. – Gili

2

Ich lief in die gleiche Frage, aber nach mehr von den Kommentaren zu lesen hier und Nachschlagewerk ich denke, Sie eine dieser beiden Möglichkeiten:

1 (was ich am Ende tut):

CompletableFuture.runAsync(() -> { 
    transporter.write(req); 
    try { 
     Rep rep = responseQueue.take(); 
     result.complete(rep); 
    } catch (Exception e) { 
     throw new CompletionException(e); 
    } 
}, executorService); 
return result; 

oder 2:

CompletableFuture<Rep> result = new CompletableFuture<>(); 
new Thread(()-> { 
    transporter.write(req); 
    try { 
     Rep rep = responseQueue.take(); 
     result.complete(rep); 
    } catch (Exception e) { 
     retsult.completeExceptionally(e); 
    } 
}).start(); 

weiß, dass ich die zweite man nicht die executorService verwendet, sondern Ich denke, der Sinn der Verwendung von CompletableFuture liegt in der Verwendung der CompletionStage-APIs im funktionalen Stil.

+0

Ihre zweiten Lösungen können verbessert werden. Detaillierte Informationen finden Sie unter http://stackoverflow.com/a/28961083/868941. – rmuller