:: Enseignements :: ESIPE :: E4INFO :: 2023-2024 :: Collections Concurrentes ::
![[LOGO]](http://igm.univ-mlv.fr/ens/resources/mlv.png) |
Volatile, Opérations atomiques et CompareAndSet
|
Algorithme lock-free et opérations atomiques
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:
public class Bogus {
private boolean stop;
public void runCounter() {
var localCounter = 0;
for(;;) {
if (stop) {
break;
}
localCounter++;
}
System.out.println(localCounter);
}
public void stop() {
stop = true;
}
public static void main(String[] args) throws InterruptedException {
var bogus = new Bogus();
var thread = new Thread(bogus::runCounter);
thread.start();
Thread.sleep(100);
bogus.stop();
thread.join();
}
}
-
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 à 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 bloc synchronized, ni lock ?
Exercice 2 - Compteur
On cherche à implanter un compteur thread-safe sous la forme d'une classe Counter et de sa méthode nextInt
qui renvoie les valeurs du compteur.
public class Counter {
private int counter;
public int nextInt() {
return counter++;
}
}
-
Expliquer pourquoi le code ci-dessus n'est pas thread-safe ?
Écrire un main démontrant le problème.
-
Que se passe-t-il si on déclare le champ counter volatile ?
-
A quoi correspond la valeur de retrour de la méthode compareAndSet de la classe
AtomicInteger ?
Utiliser la méthode compareAndSet pour créer une implantation thread-safe de la classe Counter.
-
A quoi sert la méthode getAndIncrement de la classe AtomicInteger ?
Créer une nouvelle classe Counter2, marchant comme Counter, utilisant la méthode getAndIncrement
pour obtenir une implantation thread-safe.
-
Que veut dire le terme lock-free pour un algorithme ?
Les implantations Counter et Counter2 sont-elles lock-free ?
Exercice 3 - Liste chainée lock-free
On cherche à implanter une liste chainée par insertion en tête, et on utilise pour cela le code suivant
public class Linked<E> {
private record Link<E>(E value, Link<E> next) {
private Link {
Objects.requireNonNull(value);
}
}
private Link<E> head;
/**
* Adds a non-null value at the start of the list
*/
public void addFirst(E value) {
Objects.requireNonNull(value);
head = new Link<>(value, head);
}
/**
* Applies the consumer to the elements of the list in order
*/
public void forEach(Consumer<? super E> consumer) {
Objects.requireNonNull(consumer);
for (var current = head; current != null; current = current.next) {
consumer.accept(current.value);
}
}
public static void main(String[] args) {
var list = new Linked<String>();
list.addFirst("foo");
list.addFirst("bar");
list.addFirst("baz");
list.forEach(System.out::println);
}
}
-
Expliquer pourquoi le code ci-dessus n'est pas thread-safe ?
Écrire un main démontrant le problème.
-
Modifier votre implantation pour rendre la classe Linked thread-safe (et lock-free) utilisant la classe
AtomicReference
et sa méthode compareAndSet.
-
Expliquer pourquoi utiliser la classe AtomicReference n'est pas super efficace ?
-
On souhaite ajouter la méthode pollFirst qui enlève le premier élément
ou renvoie null s'il n'y a pas de premier élément.
Voici le code non-thread safe de pollFirst :
/**
* Removes the first value of the list, otherwise, returns null.
*/
public E pollFirst() {
if (head == null) {
return null;
}
var value = head.value;
head = head.next;
return value;
}
Écrire une version lock-free de pollFirst.
-
Créer une classe Linked2 thread-safe (et lock-free) utilisant la classe
VarHandle
au lieu de la classe AtomicReference.
Rappel: les types paramétrés sont érasés à l'exécution !
-
A quoi sert la méthode
withInvokeExactBehavior() ?
Comment doit-on l'utiliser dans Linked2 ?
Faites les changements qui s'imposent.
© Université de Marne-la-Vallée