Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

    View full-size slide

  2. Florian Beaufumé
    • Architecte logiciel et expert Java
    • Freelance
    • Brown bag lunch
    • @fbeaufume

    View full-size slide

  3. • Concepts
    • Java SE
    • Java EE et Spring
    Sommaire
    @fbeaufume

    View full-size slide

  4. • "Le nombre de transistor double tous les deux ans"
    • "La fréquence double chaque 1,5 année"
    Lois de Moore
    @fbeaufume

    View full-size slide

  5. • 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

    View full-size slide

  6. • Gain maximal de latence suivant la part parallélisable du traitement
    Loi d'Amdahl
    @fbeaufume

    View full-size slide

  7. • 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

    View full-size slide

  8. • Thread safe < Immutable < Stateless
    • Section critique
    • Opération atomique
    • Contention
    • Deadlock
    • Starvation
    Définitions
    @fbeaufume

    View full-size slide

  9. • 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

    View full-size slide

  10. Java 1.0 - Threads de base
    @fbeaufume

    View full-size slide

  11. • Synchronisation de threads pour accéder à des données
    Java 1.0 - Synchronized
    @fbeaufume

    View full-size slide

  12. • Permet d'implémenter un scope request :
    • Sécurité (identité, droits)
    • Transaction
    • Tenant
    • Java 1.2 : InheritableThreadLocal
    Java 1.0 - ThreadLocal
    @fbeaufume

    View full-size slide

  13. • Exemple java.util.Timer :
    • Un thread par timer
    • Pas de garantie d'exécution
    Java 1.3 - Timers
    @fbeaufume

    View full-size slide

  14. • 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

    View full-size slide

  15. • Volatile seul
    • Synchronized en écriture + volatile
    Java 5 - Volatile
    @fbeaufume

    View full-size slide

  16. • Singleton lazy loadé classique
    • Via double checked locking
    Java 5 - Double checked locking
    @fbeaufume

    View full-size slide

  17. • ReentrantLock
    • ReentrantReadWriteLock
    Java 5 - Locks
    @fbeaufume

    View full-size slide

  18. • Coordination de threads sur des étapes
    Java 5 - CountDownLatch
    main
    workers
    await()
    countdown()
    @fbeaufume

    View full-size slide

  19. • Map
    • Hashtable : synchronisée, clés et valeurs non null
    • HashMap : pas synchronisée, accepte clés et valeurs nulles
    • ConcurrentMap
    • Etend Map
    • Méthodes atomiques comme putIfAbsent(key, value)
    • ConcurrentHashMap, implémentation efficace
    Java 5 - ConcurrentHashMap
    @fbeaufume

    View full-size slide

  20. • 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 submit(Callable task)
    Supporte scheduling, ex :
    ScheduledFuture scheduleAtFixedRate(
    Runnable command,
    long initialDelay,
    long period,
    TimeUnit unit)
    @fbeaufume

    View full-size slide

  21. Java 5 - Executors (2/2)
    @fbeaufume

    View full-size slide

  22. • Nombres atomiques
    • Semaphore
    • Et d'autres
    Java 5 - Divers
    @fbeaufume

    View full-size slide

  23. • 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

    View full-size slide

  24. Java 7 - Fork/join (2/2)
    @fbeaufume

    View full-size slide

  25. • Adder
    • Bonnes performances (reporte les ajouts si besoin)
    • Accumulator
    • Généralisation de l'Adder
    Java 8 - Adders et accumulators
    @fbeaufume

    View full-size slide

  26. 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

    View full-size slide

  27. Java 8 - StampedLock (2/2)
    @fbeaufume

    View full-size slide

  28. • 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

    View full-size slide

  29. • 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

    View full-size slide

  30. • Classe qui implémente Future et CompletionStage
    • Pour combiner/chainer des actions
    • Syntaxe fonctionnelle
    Java 8 - CompletableFuture
    @fbeaufume

    View full-size slide

  31. Java EE et Spring

    View full-size slide

  32. • 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

    View full-size slide

  33. • 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

    View full-size slide

  34. • 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

    View full-size slide

  35. • Concurrency Utilities (Java EE 7)
    • Spring
    Executors
    @fbeaufume

    View full-size slide

  36. • EJB 3.1 Timer Service (Java EE 6)
    • Concurrency Utilities (Java EE 7)
    • Spring 3
    Scheduling
    @fbeaufume

    View full-size slide

  37. • 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

    View full-size slide

  38. • 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 …"

    View full-size slide

  39. • 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

    View full-size slide

  40. • 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

    View full-size slide

  41. Merci
    @fbeaufume

    View full-size slide