Ich habe eine Methode für eine Repository-Klasse, die eine CompletableFuture
zurückgibt. Der Code, der diese Futures vervollständigt, verwendet eine Bibliothek von Dritten, die blockiert. Ich beabsichtige, eine separate begrenzte Executor
zu haben, die diese Repository-Klasse verwenden wird, um diese blockierenden Aufrufe zu machen. HierWelcher Executor wird beim Erstellen von Java CompleableFutures verwendet?
ein Beispiel:
public class PersonRepository {
private Executor executor = ...
public CompletableFuture<Void> create(Person person) {...}
public CompletableFuture<Boolean> delete(Person person) {...}
}
Der Rest meiner Anwendung werden diese Futures und tun einige andere Dinge mit den Ergebnissen zusammenstellen. Wenn diese anderen Funktionen, die an thenAccept
, thenCompose
, whenComplete
usw. geliefert werden, möchte ich nicht, dass sie auf dem Executor
für das Repository ausgeführt werden.
Ein weiteres Beispiel:
public CompletableFuture<?> replacePerson(Person person) {
final PersonRepository repo = getPersonRepository();
return repo.delete(person)
.thenAccept(existed -> {
if (existed) System.out.println("Person deleted"));
else System.out.println("Person did not exist"));
})
.thenCompose(unused -> {
System.out.println("Creating person");
return repo.create(person);
})
.whenComplete((unused, ex) -> {
if (ex != null) System.out.println("Creating person");
repo.close();
});
}
javadoc Zustände:
Aktionen für abhängige Beendigungen von nicht-Async Verfahren geliefert wird, kann durch den Thread durchgeführt werden, die den aktuellen CompletableFuture abgeschlossen ist, oder durch jede andere Aufrufer einer Abschlussmethode.
Side Frage: Warum gibt es eine oder hier? In welchem Fall gibt es einen anderen Aufrufer einer Abschlussmethode, die die aktuelle Zukunft nicht abschließt?
Hauptfrage: Wenn ich will alle println
von einem anderen Executor
als die vom Repository verwendet ein ausgeführt werden, welche Methoden muss ich async machen und die Vollstrecker von Hand zur Verfügung stellen?
Offensichtlich muss die thenAccept
in thenAcceptAsync
geändert werden, aber ich bin nicht sicher über diesen Punkt weiter.
Alternative Frage: Welcher Thread vervollständigt die zurückgegebene Zukunft von ?
Meine Vermutung ist, dass es sein wird, was auch immer Thread die Zukunft aus dem Funktionsargument ergänzt. Mit anderen Worten, ich müsste auch whenComplete
zu whenCompleteAsync
ändern.
Vielleicht bin ich über komplizierende Dinge, aber das fühlt sich an, als könnte es ziemlich schwierig werden. Ich muss sehr darauf achten, woher all diese Futures kommen. Wenn ich eine Zukunft zurückgebe, wie kann ich verhindern, dass Anrufer meinen Executor verwenden? Es fühlt sich an, als ob es die Kapselung bricht. Ich weiß, dass alle Transformationsfunktionen in Scala eine implizite ExecutionContext
annehmen, die all diese Probleme zu lösen scheint.
Lesen Sie den Artikel - http://www.nurkiewicz.com/2015/11/which-thread-executes.html. Es hilft, ein Licht auf Threads Arbeit Schatten zu werfen – rvit34