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
Antwort
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;
Was Sie getan haben, entspricht meinem. Leider kann 'CompletetFuture
Ja, aber completablefuture hat bereits die Abstraktion für ein Berechnungsergebnis, also möchte ich keinen neuen Typ für dasselbe erstellen. – GrapeBaBa
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
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);
Scheint eine Lösung – GrapeBaBa
Bitte markieren Sie es als Antwort, wenn Sie denken, dass es Ihnen geholfen hat :) – mostruash
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
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.
Ihre zweiten Lösungen können verbessert werden. Detaillierte Informationen finden Sie unter http://stackoverflow.com/a/28961083/868941. – rmuller
"* aber beide können nicht funktionieren. *" => Warum? – assylias
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
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