:: Enseignements :: ESIPE :: E4INFO :: 2013-2014 :: Java Réseau I - Concurrence et E/S ::
![[LOGO]](http://igm.univ-mlv.fr/ens/resources/mlv.png) | Atomicité, CAS |
Exercice 1 - LockFreeSet
On souhaite écrire une implantation d'un
Set
qui
soit thread-safe et sans utiliser de verrou, moniteur et autre lock.
L'implantation fonctionne comme une table de hachage de taille
fixe utilisant un hachage ouvert mais là où habituellement on
utilise une liste chainée pour stocker les élements qui entrent en collisions,
on utilisera ici des tableaux secondaires pour stocker les
éléments en collision.
Lors de l'ajout d'un élement, une fois l'index trouvé en fonction de
la fonction de hachage, on parcours le tableau secondaire pour vérifier
si l'élement ne s'y trouve pas déjà. S'il faut l'ajouter, on crée un nouveau tableau ayant une
case supplémentaire, on recopie les anciennes valeurs et on stocke le
nouvel élement dedans. Lors d'une recherche, on parcourt simplement le tableau
secondaire à l'index trouvé en fonction de la fonction de hachage.
- Expliquer pourquoi le code ci-dessus n'est pas thread-safe.
-
Modifier le code pour qu'il soit thread-safe en utilisant
les opérations atomiques de la classe
AtomicReferenceArray
et en particulier la méthode
compareAndSet.
Exercice 2 - Liste concurrente et atomicité
On souhaite écrire une implantation de liste chaînée
concurrente n'utilisant ni section critique, ni verrou.
La liste devra possèder deux méthodes
addLast(E e)
et toString()
permettant respectivement d'ajouter un élement en queue de
liste et d'afficher celle-ci. La liste sera initialement créée avec un maillon.
L'idée pour éviter toute synchronisation lors de l'ajout
consiste à récuperer le maillon à la fin de la liste puis à
tester en une opération atomique si le maillon est toujours
la fin de la liste et si oui à lui assigner le nouveau
maillon créé. Si ce n'est pas le dernier maillon, on
récupère de nouveau la fin de la liste et on recommence la
même opération.
Dans un premier temps, nous allons définir la liste comme
une chaîne de maillons: la liste elle-même est simplement
le premier maillon de la chaîne. L'ajout à la fin de la liste se
fera après un parcours du chaînage.
-
Définir la classe ConcurrentLink
avec ses champs element et
next ainsi que son constructeur
ConcurrentLink(E firstElement).
-
Expliquer pourquoi le champ element
doit être déclaré final.
-
Implanter la méthode
addLast
en utilisant pour tester et assigner en une
opération atomique, la classe
AtomicReferenceFieldUpdater
du paquetage
java.util.concurrent.atomic.
-
Implanter la méthode toString.
On souhaite maintenant séparer l'implantation de la liste de
celle
d'un maillon dans le but d'avoir une référence sur le dernier maillon
pour effectuer un ajout plus efficace.
-
Définir la classe
ConcurrentList
pour qu'elle contienne deux champs
head
et
tail
correspondant respectivement au début et à la fin de
la liste ainsi que la classe interne
Link correspondant à un maillon de la liste chaînée.
Pour simplifier les choses, la liste ne pourra pas être
vide, elle sera donc construite avec un élement.
-
Implanter la méthode
addLast
Attention, il y a un petit piège lorsque l'on met à jour la
référence correspondant à la fin de la liste.
-
Implanter la méthode
toString
.
Si vous avez réussi bravo, vous venez de ré-implanter une partie de
la classe
ConcurrentLinkedQueue
.
© Université de Marne-la-Vallée