Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

Concepts

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

• 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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

• 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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

Java SE

Slide 11

Slide 11 text

• 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

Slide 12

Slide 12 text

Java 1.0 - Threads de base @fbeaufume

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

No content

Slide 17

Slide 17 text

• 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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

• ReentrantLock • ReentrantReadWriteLock Java 5 - Locks @fbeaufume

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

• 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

Slide 23

Slide 23 text

• 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

Slide 24

Slide 24 text

Java 5 - Executors (2/2) @fbeaufume

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

No content

Slide 27

Slide 27 text

• 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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

Java 8 - StampedLock (2/2) @fbeaufume

Slide 32

Slide 32 text

• 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

Slide 33

Slide 33 text

• 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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

Java EE et Spring

Slide 36

Slide 36 text

• 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

Slide 37

Slide 37 text

• 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

Slide 38

Slide 38 text

• 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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

No content

Slide 42

Slide 42 text

• 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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

• 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

Slide 45

Slide 45 text

• 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

Slide 46

Slide 46 text

Merci @fbeaufume