Files
java-design-patterns/localization/es/async-method-invocation/README.md
T
Luis Mateo Hincapié Martinez dc7495e8bd translation: Translated all creational patterns category to Spanish (Task of issue #2277) (#2813)
* Typo corrections

* bridge pattern translated to spanish

* builder pattern translated to spanish

* context-object pattern translated to spanish

* converter pattern translated to spanish

* dependency injection pattern translated to spanish

* factory pattern translated to spanish

* factory-kit pattern translated to spanish

* factory-method pattern translated to spanish

* monostate pattern translated to spanish

* multiton pattern translated to spanish

* object mother pattern translated to spanish

* object pool pattern translated to spanish

* property pattern translated to spanish

* prototype pattern translated to spanish

* registry pattern translated to spanish

* step builder pattern translated to spanish

* value object pattern translated to spanish

* typo corrections and resources urls refactor

* grammar corrections

* Add image to each pattern

---------

Co-authored-by: luismateoh <luismateohm@gmail.com>
Co-authored-by: luis.hincapie <luis.hincapie@blankfactor.com>
2024-03-23 11:53:54 +02:00

168 lines
7.3 KiB
Markdown

---
title: Async Method Invocation
category: Concurrency
language: es
tag:
- Reactive
---
## Propósito
Asynchronous method invocation (invocación de método asincrónico) es un patrón con el que el hilo o subproceso de llamada
no se bloquea mientras espera resultados. El patrón proporciona procesamiento en paralelo de múltiples tareas independientes y recupera los resultados a través de
devoluciones de llamada (callbacks) o esperando hasta que termine el procedimiento.
## Explicación
Ejemplo cotidiano
> Lanzar cohetes espaciales es un negocio apasionante. El comandante de la misión da la orden de lanzamiento y
> después de un tiempo indeterminado, el cohete se lanza con éxito o falla miserablemente.
En otras palabras
> La invocación del método asíncrono inicia el procedimiento y vuelve inmediatamente antes de que la tarea termine
> Los resultados del procedimiento se devuelven a la llamada posteriormente (callback).
Según Wikipedia
> En la programación multiproceso, la invocación de método asíncrono (AMI), también conocida como
> llamadas de método asíncrono o el patrón asíncrono es un patrón de diseño en el que el lugar de la llamada
> no se bloquea mientras espera que termine el código llamado. En cambio, el hilo de llamada es
> notificado cuando llega la respuesta. Sondear para obtener una respuesta es una opción no deseada.
**Ejemplo programático**
En este ejemplo, estamos lanzando cohetes espaciales y desplegando vehículos lunares.
La aplicación demuestra lo que hace el patrón de invocación del método asíncrono. Las partes clave del patrón son
`AsyncResult` que es un contenedor intermedio para un valor evaluado de forma asíncrona,
`AsyncCallback` que se puede proporcionar para que se ejecute al finalizar la tarea y `AsyncExecutor` que
gestiona la ejecución de las tareas asíncronas.
```java
public interface AsyncResult<T> {
boolean isCompleted();
T getValue() throws ExecutionException;
void await() throws InterruptedException;
}
```
```java
public interface AsyncCallback<T> {
void onComplete(T value, Optional<Exception> ex);
}
```
```java
public interface AsyncExecutor {
<T> AsyncResult<T> startProcess(Callable<T> task);
<T> AsyncResult<T> startProcess(Callable<T> task, AsyncCallback<T> callback);
<T> T endProcess(AsyncResult<T> asyncResult) throws ExecutionException, InterruptedException;
}
```
`ThreadAsyncExecutor` es una implementación de `AsyncExecutor`. Se destacan algunas de sus partes clave a continuación.
```java
public class ThreadAsyncExecutor implements AsyncExecutor {
@Override
public <T> AsyncResult<T> startProcess(Callable<T> task) {
return startProcess(task, null);
}
@Override
public <T> AsyncResult<T> startProcess(Callable<T> task, AsyncCallback<T> callback) {
var result = new CompletableResult<>(callback);
new Thread(
() -> {
try {
result.setValue(task.call());
} catch (Exception ex) {
result.setException(ex);
}
},
"executor-" + idx.incrementAndGet())
.start();
return result;
}
@Override
public <T> T endProcess(AsyncResult<T> asyncResult)
throws ExecutionException, InterruptedException {
if (!asyncResult.isCompleted()) {
asyncResult.await();
}
return asyncResult.getValue();
}
}
```
Ahora está todo preparado para lanzar algunos cohetes y así poder ver cómo funciona todo.
```java
public static void main(String[] args) throws Exception {
// construye un nuevo objeto executor que ejecutará tareas asíncronas
var executor = new ThreadAsyncExecutor();
// inicia algunas tareas asíncronas con diferentes tiempos de procesamiento, las dos últimas con controladores de devolución de llamada
final var asyncResult1 = executor.startProcess(lazyval(10, 500));
final var asyncResult2 = executor.startProcess(lazyval("test", 300));
final var asyncResult3 = executor.startProcess(lazyval(50L, 700));
final var asyncResult4 = executor.startProcess(lazyval(20, 400), callback("Desplegando el rover lunar"));
final var asyncResult5 =
executor.startProcess(lazyval("devolución de llamada callback", 600), callback("Desplegando el rover lunar"));
// emula el procesamiento en el hilo o subproceso actual mientras las tareas asíncronas se ejecutan en sus propios hilos o subprocesos
Subproceso.dormir(350); // Oye, estamos trabajando duro aquí
log("El comandante de la misión está bebiendo café");
// espera a que se completen las tareas
final var result1 = executor.endProcess(asyncResult1);
final var result2 = executor.endProcess(asyncResult2);
final var result3 = executor.endProcess(asyncResult3);
asyncResult4.await();
asyncResult5.await();
// registra los resultados de las tareas, las devoluciones de las llamadas se registran inmediatamente cuando se completan
log("Cohete espacial <" + resultado1 + "> ha completado su lanzamiento");
log("Cohete espacial <" + resultado2 + "> ha completado su lanzamiento");
log("Cohete espacial <" + result3 + "> ha completado su lanzamiento");
}
```
Aquí está la salida de la consola del programa.
```java
21:47:08.227 [executor-2] INFO com.iluwatar.async.method.invocation.App - Cohete espacial <prueba> lanzado con éxito
21:47:08.269 [main] INFO com.iluwatar.async.method.invocation.App - El comandante de la misión está bebiendo café
21:47:08.318 [executor-4] INFO com.iluwatar.async.method.invocation.App - Cohete espacial <20> lanzado con éxito
21:47:08.335 [executor-4] INFO com.iluwatar.async.method.invocation.App Desplegando el rover lunar <20>
21:47:08.414 [executor-1] INFO com.iluwatar.async.method.invocation.App - Cohete espacial <10> lanzado con éxito
21:47:08.519 [executor-5] INFO com.iluwatar.async.method.invocation.App - Cohete espacial <devolución de llamada callback> lanzado con éxito
21:47:08.519 [executor-5] INFO com.iluwatar.async.method.invocation.App - Implementando el vehículo lunar <devolución de llamada callback>
21:47:08.616 [executor-3] INFO com.iluwatar.async.method.invocation.App - Cohete espacial <50> lanzado con éxito
21:47:08.617 [main] INFO com.iluwatar.async.method.invocation.App - Lanzamiento del cohete espacial <10> completado
21:47:08.617 [main] INFO com.iluwatar.async.method.invocation.App - Lanzamiento de cohete espacial <prueba> completado
21:47:08.618 [main] INFO com.iluwatar.async.method.invocation.App - Lanzamiento del cohete espacial <50> completado
```
# Diagrama de clase
![texto alternativo](./etc/async-method-invocation.png "Invocación de método asíncrono")
## Aplicabilidad
Utiliza el patrón de invocación del método asíncrono cuando
* Tienes múltiples tareas independientes que pueden ejecutarse en paralelo
* Necesitas mejorar el desempeño de un grupo de tareas secuenciales
* Tienes una cantidad limitada de capacidad de procesamiento o tareas de ejecución prolongada y la llamada no debe esperar a que las tareas estén listas
## Ejemplos cotidianos
* [FutureTask](http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/FutureTask.html)
* [CompletableFuture](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html)
* [ExecutorService](http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html)
* [Patrón asíncrono basado en tareas](https://msdn.microsoft.com/en-us/library/hh873175.aspx)