:: Enseignements :: Master :: M1 :: 2017-2018 :: Java Avancé ::
![[LOGO]](http://igm.univ-mlv.fr/ens/resources/mlv.png) | Rendez-vous et synchronization |
Exercice 1 - A vos chronometres
On cherche à savoir combien d'itérations d'une boucle on peut faire 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 (plusieurs fois), si vous avez vu juste.
-
Comment doit-on corriger le problème ?
Modifier la classe Bogus en conséquence.
-
On cherche maintenant a accélérer le code de Bogus en utilisant le mot clé volatile
au lieu des blocs synchronized.
Créer une classe BogusVolatile qui n'utilise pas de bloc synchronized.
Comment appelle-t-on les implantations qui n'ont ni blocs 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-dessous 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.
-
Depuis le jdk 1.8, la classe AtomicLong
possède une méthode updateAndGet, comment peut-on l'utiliser ici ?
Modifiez votre code en conséquence.
-
Un des inconvénients des champs "atomiques" est qu'ils alourdissent l'allocation nécessaire pour chaque objet.
En effet, pour utiliser un long pour chaque objet générateur, il faut allouer
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 implantation du générateur pseudo-aléatoire qui utilise
la classe VarHandle.
Un VarHandle 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.
Exercice 3 - Rendez vous (vous êtes cernés)
On souhaite écrire un petit programme qui permet de simuler le passage
de paramètre entre une thread qui fait un calcul et la thread principale
(celle qui exécute le
main).
-
Que se passe-t-il lorsqu'on exécute ce code ?
-
Commenter l'instruction Thread.sleep(1) dans la méthode get
puis ré-exécuter le code.
Que se passe-t-il ?
Expliquer où est le bug ?
-
Écrire une classe RendezVous qui fonctionne comme
la classe StupidRendezVous mais fonctionne correctement
lorsque l'on commente l'instruction Thread.sleep(1).
-
Regarder l'utilisation du CPU par votre programme avec la commande top.
Rappeler ce qu'est une attente active, et expliquer pourquoi la classe RendezVous en est victime.
-
Corriger le code de la classe RendezVous en utilisant les méthodes wait et notify
pour éviter l'attente active. Regardez à nouveau l'utilisation du CPU par votre programme avec la commande top.
-
Vérifiez que vous gérez les spurious wakeup correctement.
© Université de Marne-la-Vallée