:: Enseignements :: Master :: M1 :: 2016-2017 :: Java Avancé ::
[LOGO]

Rendez-vous et synchronization


Exercice 1 - A vos chronometres

On cherche à savoir combien d'itération d'une boucle on peut faire en 100 millisecondes, un de vos collègues a produit le code suivant:

  1. Sans exécuter le code, que fait ce programme ?
  2. Vérifier en exécutant le programme (plusieurs fois) si vous avez vu juste.
  3. Comment doit on corriger le problème ?
    Modifier la classe Bogus en conséquence.
  4. On cherche maintenant a accelé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 block 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).

  1. Expliquer comment fonctionne un générateur pseudo-aléatoire et pourquoi l'implantation ci-dessus n'est pas thread-safe.
  2. Utiliser la classe AtomicLong et la méthode compareAndSet pour obtenir une implantation lock-free du générateur pseudo-aléatoire.
  3. 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.
  4. 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 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 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 main (celle qui exécute le main).

  1. Que se passe-t-il lorsqu'on exécute ce code ?
  2. 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 ?
  3. Ecrire une classe RendezVous qui fonctionne comme la classe StupidRendezVous mais fonctionne correctement lorsque l'on commente l'instruction Thread.sleep(1).
  4. Rappeler ce qu'est une attente active, et expliquer pourquoi la classe RendezVous en est victime. Regarder l'utilisation du CPU par votre programme avec la commande top.
  5. 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.
  6. Vérifiez que vous gérez les spurious wakeup correctement.