Question

Il semble y avoir beaucoup de bruit autour du multicœur et de Java. Certaines personnes disent que le support Java n'est pas assez bon , il semble que ce soit un domaine à envisager. Il semble y avoir plusieurs 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.

Était-ce utile?

La solution

Recherchez les nouvelles fonctionnalités d'accès simultané Java (dans le java.util.concurrent package ) qui ont été ajoutés à Java 5. Il fournit des fonctionnalités de niveau supérieur aux Thread versions standard, ce qui facilitera la tâche (et réduira le risque d'erreur). écrire des applications concurrentes. La Leçon: concurrence de Les didacticiels Java seraient un bon point de départ.

Jusqu'à présent, je n'ai utilisé que le ExecutorService , qui permet de produire les pools de threads , auxquels de nouvelles tâches peuvent être attribuées par unités de Runnable s ou Callable s (qui peut renvoyer des valeurs après exécution sous la forme Future s), et le code de threading réel est géré par le submit.

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<Integer>() {
    public Integer call()
    {
        // Do some processing...
        return someInteger;
    }
});

Future f2 = es.submit(new Callable<Integer>() {
    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 deux get s et f2 à f1 et ultérieurement, à l'aide de la touche < => s pour récupérer le résultat.

Le problème est, une fois que <=> de <=> est appelée. Si le traitement n'est pas terminé, le programme s'arrête jusqu'à ce que le résultat de <<> puisse être récupéré. Ainsi, dans cet exemple, même si le résultat de <=> est disponible avant <=>, le programme attendra que le résultat de <=> soit disponible.

Pour ce qui est de la lecture, ma liste de livres à acheter est bientôt Concurrence Java en pratique par Brian Goetz, qui apparaît souvent lorsque la concurrence de Java est évoquée.

La page Utilitaires de concurrence de la documentation Java 5 dispose également de plus d'informations.

Autres conseils

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. fonctionnement des champs volatil et final , comment synchronisé agit à la fois comme un mutex et une barrière de mémoire , puis les nouvelles java.util.concurrent constructions

Toujours un bon conseil: si la plupart de vos cours sont immuables, tout devient tellement plus facile, car l’immuabilité supprime la nécessité de s’inquiéter des verrous pour de très rares endroits.

Découvrez le prochain cadre de jointure de fork . 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 la JVM tels que Clojure qui prétendent faciliter la programmation parallèle multicœur.

En guise d'alternative à l'approche de la concurrence en matière de mémoire partagée développée par Java, vous pouvez également consulter Concurrence basée sur les acteurs utilisant Scala au-dessus de Java, ce qui fournit un modèle plus simple pour la programmation simultanée.

Découvrez le discours de Brian Goetz De simultané à parallèle de Devoxx 2008. Pas beaucoup de conseils, mais cela vous donne une idée de l’orientation de la concurrence de Java.

Vous pouvez essayer d'utiliser une bibliothèque de modèles de parallélisme telle que Skandium pour Java. Choisissez simplement le motif de parallélisme que vous souhaitez et remplissez les crochets manquants.

Certains des modèles décrits dans Skandium sont les suivants:

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

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

Le meilleur livre contenant des conseils pratiques a été 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: Comprenez le modèle de mémoire Java (à partir de JDK 5 et versions ultérieures). La plupart des gens ne savent pas que synchronisation, volatile et final ont une signification supplémentaire allant au-delà de la portée normale du multi-threading.

Java convient aux processeurs multi-processeurs et 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, etc. Nous en sommes assez satisfaits ... JDK6 est meilleur que JDK5 et tout ce qui est en dessous est nul sur les machines multi-processeurs.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top