$30 off During Our Annual Pro Sale. View Details »

Programmation concurrente en Java

Programmation concurrente en Java

Présentation des principes de programmation concurrente et détail des solutions principales en Java.

Florian Beaufumé

March 15, 2017
Tweet

More Decks by Florian Beaufumé

Other Decks in Programming

Transcript

  1. Programmation concurrente en Java Florian Beaufumé @fbeaufume 03/2017 v1.1

  2. Florian Beaufumé • Architecte logiciel et expert Java • Freelance

    • Brown bag lunch • @fbeaufume
  3. • Concepts • Java SE • Java EE et Spring

    Sommaire @fbeaufume
  4. Concepts

  5. • "Le nombre de transistor double tous les deux ans"

    • "La fréquence double chaque 1,5 année" Lois de Moore @fbeaufume
  6. • Concurrence : • Des tâches qui peuvent se chevaucher

    • Alternées ou pas • Parallélisme : • Exécution simultanées au niveau matériel Concurrence vs parallélisme @fbeaufume
  7. • Gain maximal de latence suivant la part parallélisable du

    traitement Loi d'Amdahl @fbeaufume
  8. • Processus découpé en threads • Natif vs green •

    Ordonnancement préemptif vs coopératif • Time slicing • Fonctionnalités de distribution et coordination • Bénéfices • Utilisation des ressources • Réactivité • Couts • Complexité de conception et débugging • Ressources par thread et context switching Modèle multi-threads @fbeaufume
  9. • Thread safe < Immutable < Stateless • Section critique

    • Opération atomique • Contention • Deadlock • Starvation Définitions @fbeaufume
  10. Java SE

  11. • Concurrence intégrée au langage • Basé sur des threads

    : • Nom • Priorité : 1 à 10 • Daemon ou pas • Etat : NEW, RUNNABLE, BLOCKED, WAITING, etc. • Pile d'appel • Exemple : • Mémoire partagée suivant le Java Memory Model Java 1.0 @fbeaufume
  12. Java 1.0 - Threads de base @fbeaufume

  13. • Synchronisation de threads pour accéder à des données Java

    1.0 - Synchronized @fbeaufume
  14. • Permet d'implémenter un scope request : • Sécurité (identité,

    droits) • Transaction • Tenant • Java 1.2 : InheritableThreadLocal Java 1.0 - ThreadLocal @fbeaufume
  15. • Exemple java.util.Timer : • Un thread par timer •

    Pas de garantie d'exécution Java 1.3 - Timers @fbeaufume
  16. None
  17. • Ajout de java.util.concurrent, merci Doug Lea • Java Memory

    Model • Interactions entre les threads et la mémoire • "Happens before" • Volatile : • R et W en mémoire principale plutôt que sur cache CPU • Rend R et W 64 bits (long et double) atomique • Mais pas un incrément • Permet de la synchronisation simple Java 5 @fbeaufume
  18. • Volatile seul • Synchronized en écriture + volatile Java

    5 - Volatile @fbeaufume
  19. • Singleton lazy loadé classique • Via double checked locking

    Java 5 - Double checked locking @fbeaufume
  20. • ReentrantLock • ReentrantReadWriteLock Java 5 - Locks @fbeaufume

  21. • Coordination de threads sur des étapes Java 5 -

    CountDownLatch main workers await() countdown() @fbeaufume
  22. • Map<K, V> • Hashtable : synchronisée, clés et valeurs

    non null • HashMap : pas synchronisée, accepte clés et valeurs nulles • ConcurrentMap<K, V> • Etend Map<K, V> • Méthodes atomiques comme putIfAbsent(key, value) • ConcurrentHashMap, implémentation efficace Java 5 - ConcurrentHashMap @fbeaufume
  23. • Exécution de tâches sur pool de threads Java 5

    - Executors (1/2) Executor Executor Service ThreadPool Executor Interfaces Classes Scheduled Executor Service Scheduled ThreadPool Executor void execute(Runnable) Supporte Future, ex : Future<T> submit(Callable<T> task) Supporte scheduling, ex : ScheduledFuture scheduleAtFixedRate( Runnable command, long initialDelay, long period, TimeUnit unit) @fbeaufume
  24. Java 5 - Executors (2/2) @fbeaufume

  25. • Nombres atomiques • Semaphore • Et d'autres Java 5

    - Divers @fbeaufume
  26. None
  27. • Equivalent mono-JVM de MapReduce • Décompose une tache en

    sous-taches et recompose le résultat final • Fonctionne par work-stealing • Etendre RecursiveAction (si pas de résultat) ou RecursiveTask (si résultat) Java 7 - Fork/join (1/2) @fbeaufume
  28. Java 7 - Fork/join (2/2) @fbeaufume

  29. • Adder • Bonnes performances (reporte les ajouts si besoin)

    • Accumulator • Généralisation de l'Adder Java 8 - Adders et accumulators @fbeaufume
  30. Java 8 - StampedLock (1/2) synchronized synchronized (W) et volatile

    ReentrantLock ReentrantRWLock StampedLock Simplicité Bonnes perfs en lecture Ajout de fonctionnalités (timed wait, try lock, etc.) Bonnes perfs en lecture Bonnes perfs, fonctionnalités (upgrade de lock R en W, etc.) Fonctionnalités
  31. Java 8 - StampedLock (2/2) @fbeaufume

  32. • Execution dans le ForkJoinPool commun • Parallélisme du ForkJoinPool

    commun : • Par system property : • -Djava.util.concurrent.ForkJoinPool.common.parallelism=7 • Sinon Runtime.getRuntime().availableProcessors() - 1 • Le thread courant aussi est utilisé • Ou dans un ForkJoinPool custom Java 8 - Parallel streams (1/2) @fbeaufume
  33. • Pas toujours plus performant, varie suivant : • Type

    de collection : ArrayList plutôt que LinkedList • Nature du traitement • Taille de "N*Q" (nb d'élément * cout par élément) • Nombre de cœurs, il faut > 1 • Mesurer les deux • Par défaut utilisent tous le ForkJoinPool commun • Attention aux lambdas stateful Java 8 - Parallel streams (2/2) @fbeaufume
  34. • Classe qui implémente Future et CompletionStage • Pour combiner/chainer

    des actions • Syntaxe fonctionnelle Java 8 - CompletableFuture @fbeaufume
  35. Java EE et Spring

  36. • Modèle "thread-per-request" avec pools de thread (HTTP/Servlet, EJB) •

    Solutions Java SE fonctionnent mais… • … utiliser les threads du framework • Contextes de sécurité et de transaction • Modèles de composants (Servlet, EJB, Spring, etc) : • Cycle de vie et scope : request, session, etc. • Modèle de concurrence, voir de locking Principes généraux @fbeaufume
  37. • Servlet • SingleThreadModel est déprécié • Une instance pour

    toutes les requêtes, donc thread-safe • Spring et CDI • Concurrence manuelle via solutions de Java SE • EJB session singleton • @ConcurrencyManagement : container ou bean • @AccessTimeout • @Lock : read ou write • Autres Concurrence des composants @fbeaufume
  38. • EJB 3.1 (Java EE 6) • Spring 3 ou

    Spring Data • CDI • Peut s'implémenter via intercepteur maison • Evènements asynchrones de CDI 2 (Java EE 8) Méthodes asynchrones @fbeaufume
  39. • Concurrency Utilities (Java EE 7) • Spring Executors @fbeaufume

  40. • EJB 3.1 Timer Service (Java EE 6) • Concurrency

    Utilities (Java EE 7) • Spring 3 Scheduling @fbeaufume
  41. None
  42. • Concurrence d'accès aux données entre requêtes utilisateurs • "Transaction

    longue" quand plusieurs transactions de BD • Solutions : locking optimiste ou pessimiste Locking de persistance R1 W1 R2 W2 t Conflit @fbeaufume
  43. • Fonctionnement • OptimisticLockException en cas de problème • Pour

    faible taux de conflits • Bénéfices • Scalabilité • Portabilité • Inconvénients • Gérer le conflit : reload, force, merge Locking optimiste R W t version=3 version=4 JPA Hibernate "update … where version=3" "select …"
  44. • Fonctionnement • Pour fort taux de conflits • Bénéfices

    • Simplicité • Inconvénients • Contention • Pour transactions courtes Locking pessimiste par la base R W t "select … for update" "update …" JPA 2 Hibernate
  45. • Fonctionnement • Table de lock (id, entityClass, entityId, userId,

    date) • Pour fort taux de conflits • Bénéfices • Fonctions avancées (monitoring, historisation, etc) • Inconvénients • Mode édition dans l'UI • Gérer l'expiration des locks • Plus d'accès à la base • Contention Locking pessimiste applicatif R W t JPA Hibernate Lock Unlock
  46. Merci @fbeaufume