Últimamente he estado mirando goroutines de Go y pensé que sería bueno tener algo similar en Java. Por lo que he buscado, la forma común de paralelizar una llamada a un método es hacer algo como:
final String x = "somethingelse";
new Thread(new Runnable() {
public void run() {
x.matches("something");
}
}).start();
Eso no es muy elegante. ¿Existe una mejor manera de hacer esto? Necesitaba una solución de este tipo en un proyecto, así que decidí implementar mi propia clase contenedora en torno a una llamada al método asíncrono.
Publiqué mi clase contenedora en J-Go . Pero no sé si es una buena solución. El uso es simple:
SampleClass obj = ...
FutureResult<Integer> res = ...
Go go = new Go(obj);
go.callLater(res, "intReturningMethod", 10); //10 is a Integer method parameter
//... Do something else
//...
System.out.println("Result: "+res.get()); //Blocks until intReturningMethod returns
o menos detallado:
Go.with(obj).callLater("myRandomMethod");
//... Go away
if (Go.lastResult().isReady()) //Blocks until myRandomMethod has ended
System.out.println("Method is finished!");
Internamente, estoy usando una clase que implementa Runnable y hago un trabajo de reflexión para obtener el objeto de método correcto e invocarlo.
Quiero una opinión sobre mi pequeña biblioteca y sobre el tema de hacer llamadas a métodos asíncronos como esta en Java. ¿Es seguro? ¿Existe ya una forma más sencilla?
fuente
Respuestas:
Acabo de descubrir que hay una forma más limpia de hacer tu
(Al menos en Java 8), puede usar una expresión lambda para acortarla a:
¡Tan simple como hacer una función en JS!
fuente
Java 8 introdujo CompletableFuture disponible en el paquete java.util.concurrent.CompletableFuture, se puede utilizar para realizar una llamada asíncrona:
fuente
CompletableFuture
se mencionó en otra respuesta, pero esa usó toda lasupplyAsync(...)
cadena. Este es un envoltorio simple que se ajusta perfectamente a la pregunta.ForkJoinPool.commonPool().execute()
tiene un poco menos de gastos generalesEs posible que desee considerar también la clase
java.util.concurrent.FutureTask
.Si está utilizando Java 5 o posterior, FutureTask es una implementación llave en mano de "Un cálculo asincrónico cancelable ".
Hay comportamientos de programación de ejecución asincrónica aún más ricos disponibles en el
java.util.concurrent
paquete (por ejemplo,ScheduledExecutorService
), peroFutureTask
pueden tener toda la funcionalidad que necesita.Incluso iría tan lejos como para decir que ya no es recomendable utilizar el primer patrón de código que dio como ejemplo desde que
FutureTask
estuvo disponible. (Suponiendo que esté en Java 5 o posterior).fuente
No me gusta la idea de usar Reflection para eso.
No solo es peligroso por perderlo en alguna refactorización, sino que también puede ser negado por
SecurityManager
.FutureTask
es una buena opción como las otras opciones del paquete java.util.concurrent.Mi favorito para tareas simples:
un poco más corto que crear un hilo (la tarea es invocable o ejecutable)
fuente
ExecutorService
instancia, para que pueda llamarshutdown()
cuando sea necesario.Puede usar la sintaxis Java8 para CompletableFuture, de esta manera puede realizar cálculos asíncronos adicionales basados en el resultado de llamar a una función asíncrona.
por ejemplo:
Se pueden encontrar más detalles en este artículo.
fuente
Puede utilizar la
@Async
anotación de jcabi-aspectos y AspectJ:Cuando llamas
save()
, se inicia un nuevo hilo y ejecuta su cuerpo. Tu hilo principal continúa sin esperar el resultado desave()
.fuente
Puede usar Future-AsyncResult para esto.
Referencia: https://spring.io/guides/gs/async-method/
fuente
Java también proporciona una buena forma de llamar a métodos asíncronos. en java.util.concurrent tenemos ExecutorService que ayuda a hacer lo mismo. Inicializa tu objeto así:
y luego llame a la función como-
fuente
Probablemente no sea una solución real, pero ahora, en Java 8, puede hacer que este código se vea al menos un poco mejor usando la expresión lambda.
E incluso podría hacer esto en una línea, aún teniendo bastante legibilidad.
fuente
Puedes usar
AsyncFunc
de Cactoos :Se ejecutará en segundo plano y el resultado estará disponible en
get()
formatoFuture
.fuente
Esto no está realmente relacionado, pero si tuviera que llamar de forma asincrónica a un método, por ejemplo, coincide con (), usaría:
Luego, para llamar al método asincrónico, usaría:
He probado esto y funciona. Pensé que podría ayudar a otros si simplemente vinieran por el "método asincrónico".
fuente
También hay una buena biblioteca para Async-Await creada por EA: https://github.com/electronicarts/ea-async
De su archivo Léame:
Con EA Async
Sin EA Async
fuente