Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Java 7 - Fork/Join

8,155 views

Published on

Présentation de Fork/Join dans Java 7 par Olivier Croisier, Benoît Nouyrigat et Lucien Pereira, de Zenika.

Cette présentation a été donnée lors d'une fête en l'honneur de la sortie de Java 7, co-organisée par Xebia et Zenika (cf. http://sortiejava7.eventbrite.com ).

Published in: Technology, News & Politics
  • Be the first to comment

  • Be the first to like this

Java 7 - Fork/Join

  1. 2. Zenika <ul><li>Zenika est un cabinet de conseil en architecture informatique.
  2. 3. 3 domaines d'expertise centrés sur la plate-forme Java. </li><ul><li>La formation </li></ul></ul>Centre de formation au coeur de Paris. Spring, Hibernate, Maven, Eclipse RCP, BIRT, GWT, etc... <ul><ul><li>Le conseil </li></ul></ul>Audits de code et d'architecture, préconisations et mise en place de frameworks, choix et évaluation d'outils et de frameworks, etc... <ul><ul><li>La réalisation </li></ul></ul>Approche pragmatique de nos architectes - nous réalisons ce que nous préconisons. Délégation de projets au forfait.
  3. 4. Speakers <ul><li>Lucien Pereira Consultant Zenika </li></ul><ul><li>Benoît Nouyrigat Consultant Zenika </li></ul><ul><li>Olivier Croisier Consultant Zenika </li></ul>
  4. 5. Plan <ul><li>Introduction
  5. 6. Le framework Fork / Join
  6. 7. Use-cases et bonnes pratiques
  7. 8. Démos
  8. 9. Conclusion </li></ul>
  9. 10. Introduction Java 7 <ul><li>Première version majeure depuis 2006
  10. 11. Première version dirigée par Oracle
  11. 12. Contenu : </li><ul><li>Project Coin
  12. 13. NIO2
  13. 14. Fork / Join
  14. 15. InvokeDynamic
  15. 16. Autres </li></ul><li>En attendant Java 8... </li></ul>
  16. 17. Introduction Pourquoi Fork / Join <ul><li>Les processeurs multiples sont omniprésents </li><ul><li>Desktops, Laptops, Tablettes, Téléphones ! </li></ul><li>Il faut en tirer parti </li><ul><li>Programmation multi-threadée
  17. 18. Algorithmes parallèles </li></ul><li>Design patterns parallèles </li><ul><li>Fork / Join = Map / Reduce </li></ul><li>Frameworks </li><ul><li>Hadoop, GridGain... </li></ul></ul>
  18. 19. Introduction Principe du Fork / Join <ul><li>Un problème doit être traité. Il est modélisé sous la forme d'une tâche soumise à un pool de threads
  19. 20. Cette tâche </li><ul><li>Constate que le problème peut être décomposé en sous-problèmes indépendants, donc parallélisables
  20. 21. Crée une nouvelle tâche par sous-problème
  21. 22. Les soumet au pool en appelant fork()
  22. 23. Attend leur complétion en appelant join()
  23. 24. Fusionne les résultats partiels
  24. 25. Renvoie le résultat final </li></ul></ul>
  25. 26. Le framework Fork / Join ForkJoinPool <ul><li>Package java.util.concurrent
  26. 27. Famille des Executors </li></ul>T invoke(task) void execute(task) Future<T> submit(task) < interface> Executor < interface> ExecutorService ForkJoinPool
  27. 28. Le framework Fork / Join ForkJoinPool <ul><li>Instanciation </li><ul><li>new ForkJoinPool([int nbThreads]);
  28. 29. Par défaut nbThreads = nombre de processeurs
  29. 30. ThreadFactory et UncaughtExceptionHandler réglables </li></ul><li>Utilisation </li></ul>private static ForkJoinPool pool = new ForkJoinPool() ; public void sort(long[] array) { pool.invoke (new ArraySortTask(...)); }
  30. 31. Le framework Fork / Join ForkJoinPool TASK
  31. 32. Le framework Fork / Join ForkJoinTask <ul><li>Un ForkJoinPool exécute des ForkJoinTasks </li></ul>compute(), fork(), join() isDone(), get() ... < interface> Future<V> < abstract> ForkJoinTask<V> RecursiveTask<V> RecursiveAction
  32. 33. Le framework Fork / Join ForkJoinTask <ul><li>RecursiveTask<V> </li><ul><li>Implémente Future<V>
  33. 34. Modélise un traitement récursif qui renvoie une valeur </li><ul><li>Ex : calculer la taille totale d'une arborescence de fichiers </li></ul></ul><li>RecursiveAction </li><ul><li>Implémente Future<Void>
  34. 35. Modélise un traitement qui ne renvoie pas de valeur
  35. 36. Peut néanmoins modifier les données passées en paramètre </li><ul><li>Ex : trier un tableau &quot;in-place&quot; </li></ul></ul></ul>
  36. 37. Le framework Fork / Join RecursiveTask<V> <ul><li>RecursiveTask<V> </li></ul>fork fork fork join join join fork join fork join fork join +1 +1 +1 +1 +1 +1 1 2 3 4 +1 2 3 4 5 1 2 2 3 3 4 4 5 1 2 2 3 3 4 4 5
  37. 38. Le framework Fork / Join RecursiveTask<V> - Mauvais exemple public class FileSizeTask extends RecursiveTask<Long> { private File root; public FileSizeTask(File root) { this.root = root; } protected Long compute() { long size = 0; File[] files = root.listFiles(); for (File f : files) { if (f.isDirectory()) { ForkJoinTask<Long> subtask = new FileSizeTask(f).fork() ; size += subtask.join() ; } else { size += f.length(); } } return size; } }
  38. 39. Le framework Fork / Join RecursiveTask<V> - Bon exemple public class FileSizeTask extends RecursiveTask<Long> { private File root; public FileSizeTask(File root) { this.root = root; } protected Long compute() { List<ForkJoinTask<Long>> subTasks = new ArrayList<>(); long size = 0; File[] files = root.listFiles(); for(File f : files) { if (f.isDirectory()) { subTasks.add(new FileSizeTask(f).fork()) ; } else { size += f.length(); } } for (ForkJoinTask<Long> subTask : subTasks) { size += subTask.join(); } return size; } } //
  39. 40. Le framework Fork / Join RecursiveAction <ul><li>RecursiveAction </li></ul>fork join fork join fork fork join join join fork join fork +1 +1 1 2 3 4 2 3 4 5 1 2 3 4 +1 1 2 3 4 2 2 3 4 +1 1 2 3 4 1 3 3 4 +1 1 2 3 4 1 2 4 4 +1 1 2 3 4 1 2 3 5 2 3 3 4 +1 1 2 3 4 1 2 4 5
  40. 41. Use-cases et bonnes pratiques Use-cases <ul><li>Le design pattern Fork / Join est adapté : </li><ul><li>En environnement multi-processeurs
  41. 42. Lorsque le traitement est décomposable en sous-tâches indépendantes </li><ul><li>Existence d'algorithmes parallèles spécifiques </li></ul></ul><li>La décomposition en sous-tâches peut être : </li><ul><li>statique : découper un tableau en zones fixes
  42. 43. dynamique : découvrir une arborescence de fichiers </li><ul><li>Attention à maîtriser le volume de tâches créées ! </li></ul></ul></ul>
  43. 44. Use-cases et bonnes pratiques Bonnes pratiques <ul><li>Attention au coût de gestion </li><ul><li>Le bénéfice obtenu en parallélisant un traitement doit être supérieur au coût de gestion par le framework
  44. 45. Trouver la bonne granularité </li></ul><li>Attention à la consommation mémoire </li><ul><li>Grosses structures : préférer la modification &quot;in-place&quot;
  45. 46. Découverte dynamique des sous-tâches </li></ul><li>Attention à la complexité </li><ul><li>Optimisation prématurée ?
  46. 47. Maintenance </li></ul></ul>
  47. 48. Use-cases et bonnes pratiques Optimisations <ul><li>Framework Fork / Join </li><ul><li>&quot;Work stealing&quot;
  48. 49. Threads >= Degré de parallélisme </li><ul><li>Les tâches en attente de join() sont mises de côté pour permettre à d'autres tâches d'être traitées </li></ul></ul><li>Tâches </li><ul><li>Eviter la synchronisation manuelle </li><ul><li>Utiliser fork() et join() uniquement </li></ul><li>Optimiser la granularité à l'aide des statistiques du pool </li><ul><li>getQueuedSubmissionCount() , getStealCount() ...
  49. 50. Possibilité d'optimisation dynamique </li></ul></ul></ul>
  50. 51. Démos !
  51. 52. Références <ul><li>API Java 7, package java.util.concurrent http://download.java.net/jdk7/docs/api/
  52. 53. Etude de Doug Lea http://gee.cs.oswego.edu/dl/papers/fj.pdf
  53. 54. Article de Julien Ponge http://www.oracle.com/technetwork/articles/java/fork-join-422606.html
  54. 55. Article de José Paumard http://blog.paumard.org/2011/07/05/java-7-fork-join/ </li></ul>
  55. 56. Questions ?

×