J'ai regardé les goroutines de Go ces derniers temps et j'ai pensé que ce serait bien d'avoir quelque chose de similaire à Java. Dans la mesure où j'ai cherché, la manière courante de paralléliser un appel de méthode est de faire quelque chose comme:
final String x = "somethingelse";
new Thread(new Runnable() {
public void run() {
x.matches("something");
}
}).start();
Ce n'est pas très élégant. Existe-t-il une meilleure façon de le faire? J'avais besoin d'une telle solution dans un projet, j'ai donc décidé d'implémenter ma propre classe wrapper autour d'un appel de méthode async.
J'ai publié ma classe wrapper dans J-Go . Mais je ne sais pas si c'est une bonne solution. L'utilisation est 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
ou moins verbeux:
Go.with(obj).callLater("myRandomMethod");
//... Go away
if (Go.lastResult().isReady()) //Blocks until myRandomMethod has ended
System.out.println("Method is finished!");
En interne, j'utilise une classe qui implémente Runnable et j'effectue un travail de réflexion pour obtenir l'objet de méthode correct et l'appeler.
Je veux avoir une opinion sur ma petite bibliothèque et sur le sujet de faire des appels de méthode async comme celui-ci en Java. Est-ce sûr? Existe-t-il déjà un moyen plus simple?
la source
Réponses:
Je viens de découvrir qu'il existe une manière plus propre de faire votre
(Au moins en Java 8), vous pouvez utiliser une expression lambda pour la raccourcir en:
Aussi simple que de créer une fonction dans JS!
la source
Java 8 a introduit CompletableFuture disponible dans le package java.util.concurrent.CompletableFuture, peut être utilisé pour effectuer un appel asynchrone:
la source
CompletableFuture
a été mentionné dans une autre réponse, mais celle-ci a utilisé toute lasupplyAsync(...)
chaîne. Ceci est un emballage simple qui répond parfaitement à la question.ForkJoinPool.commonPool().execute()
a un peu moins de frais générauxVous pouvez également envisager la classe
java.util.concurrent.FutureTask
.Si vous utilisez Java 5 ou une version ultérieure, FutureTask est une implémentation clé en main de «Un calcul asynchrone annulable».
Il existe des comportements de planification d'exécution asynchrone encore plus riches disponibles dans le
java.util.concurrent
package (par exemple,ScheduledExecutorService
), maisFutureTask
peuvent avoir toutes les fonctionnalités dont vous avez besoin.J'irais même jusqu'à dire qu'il n'est plus conseillé d'utiliser le premier modèle de code que vous avez donné comme exemple depuis qu'il
FutureTask
est devenu disponible. (En supposant que vous utilisez Java 5 ou une version ultérieure.)la source
Je n'aime pas l'idée d'utiliser Reflection pour ça.
Non seulement dangereux de l'avoir manqué dans une refactorisation, mais il peut également être nié par
SecurityManager
.FutureTask
est une bonne option comme les autres options du package java.util.concurrent.Mon préféré pour les tâches simples:
un peu plus court que la création d'un thread (la tâche est un appelable ou un exécutable)
la source
ExecutorService
instance, afin que vous puissiez appelershutdown()
lorsque vous en avez besoin.Vous pouvez utiliser la syntaxe Java8 pour CompletableFuture, de cette façon, vous pouvez effectuer des calculs asynchrones supplémentaires basés sur le résultat de l'appel d'une fonction asynchrone.
par exemple:
Plus de détails peuvent être trouvés dans cet article
la source
Vous pouvez utiliser l'
@Async
annotation de jcabi-aspects et AspectJ:Lorsque vous appelez
save()
, un nouveau thread démarre et exécute son corps. Votre thread principal continue sans attendre le résultat desave()
.la source
Vous pouvez utiliser Future-AsyncResult pour cela.
Référence: https://spring.io/guides/gs/async-method/
la source
Java fournit également un bon moyen d'appeler des méthodes asynchrones. dans java.util.concurrent, nous avons ExecutorService qui aide à faire de même. Initialisez votre objet comme ceci -
puis appelez la fonction comme-
la source
Ce n'est probablement pas une vraie solution, mais maintenant - dans Java 8 - vous pouvez rendre ce code au moins un peu meilleur en utilisant l'expression lambda.
Et vous pouvez même le faire en une seule ligne, en l'ayant toujours assez lisible.
la source
Vous pouvez utiliser à
AsyncFunc
partir de Cactoos :Il sera exécuté en arrière-plan et le résultat sera disponible au
get()
formatFuture
.la source
Ce n'est pas vraiment lié, mais si je devais appeler une méthode de manière asynchrone, par exemple matches (), j'utiliserais:
Ensuite, pour appeler la méthode asynchrone, j'utiliserais:
J'ai testé cela et cela fonctionne. Je pensais juste que cela pourrait aider les autres s'ils venaient simplement pour la "méthode asynchrone".
la source
Il existe également une belle bibliothèque pour Async-Await créée par EA: https://github.com/electronicarts/ea-async
De leur Readme:
Avec EA Async
Sans EA Async
la source