Astuces pour coder des programmes Java dans un scénario multicœur

Il semble y avoir beaucoup de bruit autour du multicœur et du java. Bien que certaines personnes disent que le support Java n’est pas assez bon , il semble que ce soit un domaine à envisager. Il semble y avoir de nombreuses techniques pour améliorer les performances des programmes concurrents.

Tous les conseils et astuces concernant la programmation dans un scénario multicœur sont appréciés.

Examinez les nouvelles fonctionnalités d’access simultané Java (dans le package java.util.concurrent ) qui ont été ajoutées à Java 5. Cette fonctionnalité offre des fonctionnalités de niveau supérieur aux Thread classiques, ce qui facilitera la tâche (et réduira le risque d’erreur). pour écrire des applications concurrentes. La leçon: La simultanéité des didacticiels Java serait un bon sharepoint départ.

Jusqu’à présent, j’ai seulement utilisé ExecutorService , qui permet de produire des pools de threads , auxquels de nouvelles tâches peuvent être atsortingbuées dans des unités Runnable s ou Callable s (pouvant renvoyer des valeurs après exécution sous la forme Future s), ainsi que le thread actuel. le code est géré par ExecutorService .

Par exemple, effectuer un calcul en utilisant un pool de threads de 2 threads et obtenir le résultat peut être aussi simple que:

 ExecutorService es = Executors.newFixedThreadPool(2); Future f1 = es.submit(new Callable() { public Integer call() { // Do some processing... return someInteger; } }); Future f2 = es.submit(new Callable() { public Integer call() { // Do some processing... return someInteger; } }); Integer firstInteger = f1.get(); Integer secondInteger = f2.get(); 

Dans le code ci-dessus (non testé), tout ce qui me préoccupe est de créer quelques Callable et de le submit à ExecutorService , puis à utiliser Future pour extraire le résultat.

La capture est, une fois que la méthode get du Future est appelée, si le traitement n’est pas terminé, le programme s’arrête jusqu’à ce que le résultat du Future puisse être récupéré. Ainsi, dans cet exemple, même si le résultat de f2 est disponible avant f1 , le programme attendra que le résultat de f1 soit disponible.

Pour ce qui est de la lecture, ma liste de livres à acheter est bientôt: Concurrence pratique en pratique de Brian Goetz, qui apparaît souvent lorsqu’on parle de simultanéité en Java.

La page Utilitaires de concurrence de la documentation Java 5 contient également des informations supplémentaires.

Le meilleur conseil doit être: obtenez votre synchronisation correcte!

Cela peut sembler un peu évident, mais une compréhension du modèle de mémoire Java est essentielle, en particulier du fonctionnement des champs volatils et finaux , de la manière dont Synchronized agit à la fois comme un mutex et une barrière de mémoire , puis des nouvelles constructions java.util.concurrent

Toujours un bon conseil: si la plupart de vos cours sont immuables, tout devient tellement plus facile, car l’immutabilité élimine la nécessité de s’inquiéter des verrous pour de nombreux endroits préoccupants.

Découvrez le prochain framework fork-join . Le framework fork-join permet aux développeurs d’obtenir un parallélisme fin sur les architectures multicœurs.

Vous pouvez également consulter des langages basés sur JVM tels que Clojure, qui prétendent faciliter la programmation parallèle multicœur.

En guise d’alternative à l’approche Java de la mémoire partagée propre à Java, vous pouvez également vous intéresser à la concurrence d’access basée sur Actor utilisant Scala au-dessus de Java, qui fournit un modèle plus simple pour la programmation simultanée.

Découvrez le discours de Brian Goetz Du concurrent au parallèle de Devoxx 2008. Peu de conseils, mais cela vous donne une idée de l’orientation de la simultanéité Java.

Vous pouvez essayer d’utiliser une bibliothèque de motifs de parallélisme telle que Skandium pour Java. Choisissez simplement le modèle de parallélisme souhaité et remplissez les crochets manquants.

Certains des modèles présentés dans Skandium sont:

  • Maître-esclave: Farm(nested);
  • Pipeline: `Pipe (stage1, stage2);
  • Pour l’itération: For(nested, i);
  • Itération conditionnelle: While(nested, condition);
  • If(condition, trueCase, falseCase); conditionnel: If(condition, trueCase, falseCase);
  • Carte-réduction: Map(split, nested, merge);
  • Réduction de la carte avec différents chemins de code: Fork(split, nested, merge);
  • Diviser et conquérir récursivement: DaC(condition, split, nested, merge);

Tous les modèles peuvent être nesteds et combinés afin que vous puissiez avoir une ferme à l’intérieur d’une division et conquête, etc.

Le meilleur livre avec des conseils pratiques a été la concurrence Java en pratique . C’est une lecture incontournable pour tous les programmeurs Java, même ceux qui pensent qu’ils ne font pas de programmation simultanée, car Java contient de nombreux threads cachés dans ses différentes bibliothèques (on pense à Swing, comme avec les servlets).

Mon conseil: comprendre le modèle de mémoire Java (à partir de JDK 5 et supérieur). La plupart des gens ne savent pas que synchronisation, volatile et final ont une signification supplémentaire allant au-delà de la scope normale du multi-threading.

Java convient aux multi-processeurs et aux multi-cœurs. Si vous le programmez correctement et que vous investissez un peu dans votre cerveau, vous obtenez un système de serveur hautement concurrentiel qui utilise 8 cœurs, ce qui nécessite beaucoup de synchronisation et ainsi de suite. Nous en sums assez satisfaits … JDK6 est meilleur que JDK5 et tout ce qui suit craint les machines multi-cpu.