Ultimamente, tenho visto as goroutines do Go e achei que seria bom ter algo semelhante em Java. Tanto quanto eu procurei a maneira comum de paralelizar uma chamada de método é fazer algo como:
final String x = "somethingelse";
new Thread(new Runnable() {
public void run() {
x.matches("something");
}
}).start();
Isso não é muito elegante. Existe um jeito melhor de fazer isso? Como eu precisava dessa solução em um projeto, decidi implementar minha própria classe de wrapper em torno de uma chamada de método assíncrona.
Publiquei minha classe de wrapper no J-Go . Mas não sei se é uma boa solução. O uso é simples:
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
ou menos detalhado:
Go.with(obj).callLater("myRandomMethod");
//... Go away
if (Go.lastResult().isReady()) //Blocks until myRandomMethod has ended
System.out.println("Method is finished!");
Internamente, estou usando uma classe que implementa Runnable e faço algum trabalho de reflexão para obter o objeto de método correto e invocá-lo.
Eu quero uma opinião sobre minha pequena biblioteca e sobre o assunto de fazer chamadas de método assíncronas como esta em Java. É seguro? Já existe uma maneira mais simples?
fonte
Respostas:
Acabei de descobrir que existe uma maneira mais limpa de fazer sua
(Pelo menos no Java 8), você pode usar uma expressão lambda para reduzi-la para:
Tão simples quanto criar uma função em JS!
fonte
O Java 8 introduziu o CompletableFuture disponível no pacote java.util.concurrent.CompletableFuture, pode ser usado para fazer uma chamada assíncrona:
fonte
CompletableFuture
foi mencionado em outra resposta, mas essa usou toda asupplyAsync(...)
cadeia. Este é um invólucro simples que se encaixa perfeitamente na pergunta.ForkJoinPool.commonPool().execute()
tem um pouco menos despesas geraisVocê também pode considerar a classe
java.util.concurrent.FutureTask
.Se você estiver usando o Java 5 ou posterior, o FutureTask é uma implementação chave na mão de "Uma computação assíncrona cancelável".
Existem comportamentos de agendamento de execução assíncrona ainda mais ricos disponíveis no
java.util.concurrent
pacote (por exemploScheduledExecutorService
), masFutureTask
podem ter toda a funcionalidade necessária.Eu chegaria ao ponto de dizer que não é mais aconselhável usar o primeiro padrão de código que você deu como exemplo desde que
FutureTask
se tornou disponível. (Supondo que você esteja no Java 5 ou posterior.)fonte
não gosto da ideia de usar o Reflection para isso.
Não é apenas perigoso por faltar em alguma refatoração, mas também pode ser negado
SecurityManager
.FutureTask
é uma boa opção, como as outras opções do pacote java.util.concurrent.O meu favorito para tarefas simples:
um pouco mais curto que a criação de um Thread (a tarefa é Callable ou Runnable)
fonte
ExecutorService
instância, para que você possa ligarshutdown()
quando precisar.Você pode usar a sintaxe Java8 para CompletableFuture, desta forma, poderá executar cálculos assíncronos adicionais com base no resultado da chamada de uma função assíncrona.
por exemplo:
Mais detalhes podem ser encontrados neste artigo
fonte
Você pode usar a
@Async
anotação em jcabi-aspect e AspectJ:Quando você chama
save()
, um novo thread inicia e executa seu corpo. Seu segmento principal continua sem aguardar o resultado desave()
.fonte
Você pode usar o Future-AsyncResult para isso.
Referência: https://spring.io/guides/gs/async-method/
fonte
Java também fornece uma boa maneira de chamar métodos assíncronos. em java.util.concurrent , temos ExecutorService que ajuda a fazer o mesmo. Inicialize seu objeto assim -
e depois chame a função como
fonte
Provavelmente não é uma solução real, mas agora - no Java 8 - você pode fazer esse código parecer um pouco melhor usando a expressão lambda.
E você pode até fazer isso em uma linha, mantendo-a bem legível.
fonte
Você pode usar
AsyncFunc
do Cactoos :Ele será executado em segundo plano e o resultado estará disponível em
get()
aFuture
.fonte
Isso não está realmente relacionado, mas se eu chamasse um método de forma assíncrona, por exemplo, match (), usaria:
Então, para chamar o método assíncrono, eu usaria:
Eu testei isso e funciona. Apenas pensei que poderia ajudar os outros se eles viessem para o "método assíncrono".
fonte
Também existe uma biblioteca agradável para o Async-Await criada pela EA: https://github.com/electronicarts/ea-async
Do Leiame:
Com o EA Async
Sem EA Async
fonte