In JAX-RS werden die @Suspend
Annotation und AsyncResponse
nur in bestimmten typischen Szenarien benötigt. Das erste Szenario wurde bereits in Ihrem Codebeispiel identifiziert. Es sind lange laufende Aufgaben. In diesem Fall kann AsyncResponse
verwendet werden, um lange laufenden Code in einem Hintergrund-Thread auszuführen. Obwohl dies auf den ersten Blick nicht sinnvoll ist, müssen wir uns überlegen, wie ein Anwendungsserver/Container seine Anforderungen behandelt. Normalerweise gibt es einen Pool von Threads, der Clientanforderungen akzeptiert und verarbeitet. Wenn Sie kostspielige Operationen inline in Ihren JAX-RS-Service-Methoden implementieren, wird einer der Threads im Pool für die gesamte Laufzeit blockiert. Mit der AsyncResponse
wird der Executor-Thread in den Pool zurückgegeben und andere Anfragen können parallel bedient werden.
@Path("/users")
public class UserRestService {
@GET
public void getAllUsers(@Suspend final AsyncResponse asyncResponse) {
new Thread(new Runnable(
@Override
public void run() {
List<Users> users = UserDAO.loadAllUsers();
asyncResponse.resume(users);
}
) {}).start();
}
}
Das zweite Anwendungsszenario für AsyncResponse
ist die oft von Produzenten Konsummuster gesehen Muster. Angenommen, Sie haben eine Warteschlange an die URL https://yourservice.at/queue/next
gebunden, dann kann eine @GET
Methode für eine Blockierung take()
verwendet werden, zum Beispiel eine LinkedBlockingQueue
. Unter derselben URL können Sie eine @POST
-Methode binden, die Daten zur Warteschlange hinzufügt. In diesem Fall würden Sie die Funktionalität mit der Operation take()
in einer AsyncResponse
einpacken.
@Path("/queue/next")
public class MessageQueueService {
private static final LinkedBlockingQueue<AsyncResponse> suspendedResponses = new LinkedBlockingQueue<AsyncResponse>();
@GET
public void getNextMessage(@Suspend final AsyncResponse asyncResponse) {
MessageQueueService.suspendedResponses.put(asyncResponse);
}
@POST
public void putNewMessage(final String message) throws InterruptedException {
AsyncResponse asyncResponse = suspendedResponses.take(); // note how this could also block a thread
asyncResponse.resume(message);
}
}
Aus diesen Erklärungen auch sehen können, dass die JAX-RS @Suspended
Mechanismus verwendet wird, um eine asynchrone Serverseite Aufgabe zu erstellen. Ob die gleiche Anfrage auch asynchron auf dem Client ausgeführt wird oder nicht, ist eine ganz andere Geschichte.
Nein. Asynchron auf dem Client bedeutet nicht asynchron auf dem Server und * umgekehrt. * Treffen Sie Ihre eigene Entscheidung an jedem Ende unabhängig. – EJP
Sie sollten Async auf dem Server für lange laufende Aufgaben verwenden, damit die Container-Threads nicht gehalten werden. –