:: Enseignements :: Master :: M1 :: 2014-2015 :: Java Avancé ::
![[LOGO]](http://igm.univ-mlv.fr/ens/resources/mlv.png) | Volatile, Atomic, Compare and Set |
Exercice 1 - A vos chronometres
On cherche à savoir combien on peut faire d'itération d'une boucle en 100 millisecondes,
un de vos collègues a produit le code suivant:
-
Sans exécuter le code, que fait ce programme ?
-
Vérifier en exécutant le programme si vous avez vu juste.
-
Comment doit on corriger le problème ?
Modifier la classe Bogus en conséquence.
-
On cherche maintenant a accelérer le code de bogus et en utilisant le mot clé volatile au lieu des blocs synchronized.
Créer une classe BogusVolatile qui n'utilise pas de block synchronized.
Comment appele t'on les implantations qui n'ont ni block synchronized ni lock ?
Exercice 2 - Generateur pseudo-aléatoire lock-free
On souhaite modifier la classe
RandomNumberGenerator pour la rendre thread-safe
sans utiliser ni section critique ni verrou (
lock free donc).
-
Expliquer comment fonctionne un générateur pseudo-aléatoire et
pourquoi l'implantation ci-dessus n'est pas thread-safe.
-
Utiliser la classe
AtomicLong et la méthode compareAndSet
pour obtenir une implantation lock-free du générateur pseudo aléatoire.
-
Un des inconvénients des champs "atomiques" est qu'ils allourdissent l'allocation nécessaire pour chaque objet.
En effet, pour utiliser un long pour chaque objet générateur, il faut alloouer pour chacun des
objets un AtomicLong qui permettra lui-même d'accéder de manière atomique à la valeur d'un long,
chaque accès nécessitant lui-même une indirection...
Faites une nouvelle implémentation du générateur pseudo aléatoire qui utilise un AtomicLongFieldUpdater
de la classe AtomicLongFieldUpdater
qui ne nécessite qu'une seule instance (static) pour mettre à jour de manière atomique le champ volatile long de n'importe lequel des objets générateur de cette classe.
-
Depuis le jdk 1.8, vos deux classes précédentes peuvent utiliser la méthode updateAndGet
sur AtomicLong
comme sur AtomicLongFieldUpdater.
Modifiez votre code en conséquence.
Exercice 3 - Liste concurrente et atomicité
On souhaite écrire une implantation de liste chaînée de chaînes de caractères
avec insertion à la fin, concurrente et n'utilisant ni section critique, ni verrou.
La liste devra possèder deux méthodes
addLast(E e) et
forEach()
permettant respectivement d'ajouter un élement en fin de la liste et
d'appeler un
java.util.function.Consumer sur l'ensemble des élements de la liste.
Le code ci-dessous est une implantation non-thread safe de la liste
Détail d'implantation, pour éviter de gérer différemment le cas de la liste vide,
une liste est crée initialement avec un maillon contenant la valeur
null.
L'idée de l'algorithme concurrent est la suivante:
pour éviter toute synchronisation lors de l'ajout,
on récupere le maillon à la fin de la liste puis on
teste en utilisant une opération atomique si le maillon est
toujours la fin de la liste; si oui, on lui assigner le nouveau
maillon créé. Si ce n'est pas le dernier maillon, on
récupère de nouveau le maillon à la fin de la liste et
on recommence la même opération...
-
Recopier le code de la classe StringList dans
une classe LockFreeStringList qui va implanter une liste
threadsafe sans verrou.
Dans un premier temps, implanter la méthode addLast
en utilisant la classe
AtomicReferenceFieldUpdater.
Comment doit-on modifier le code de forEach pour
que la méthode soit thread-safe ?
-
On souhaite améliorer la complexité de la méthode addLast
en maintenant, en plus d'une référence sur la tête de la liste
(head), une référence sur la queue de la liste
(tail).
Modifier l'implantation de addLast pour utiliser
le champ tail et le mettre à jour.
© Université de Marne-la-Vallée