:: Enseignements :: ESIPE :: E4INFO :: 2009-2010 :: Java Réseau I - Concurrence et E/S ::
![[LOGO]](http://igm.univ-mlv.fr/ens/resources/mlv.png) | Examen - Réseau - Concurrence & I/O (Septembre) |
Exercice 1 - Question de cours
Chaque explication devra faire entre trois et sept lignes
(Eviter le bavardage, SVP) et surtout répondez à la question.
-
A quoi servent les classes du package java.util.concurrent.atomic.
Quelles sont les avantages/inconvénients par rapport à l'utilisation
de moniteur avec le bloc synchronized.
-
Le code suivant a t'il un problème de publication ?
public class Entry {
private volatile int value;
private long key;
public Entry(int value, long key) {
this.value = value;
this.key = key;
}
}
Si oui, pourquoi ? si non pourquoi ?
-
Pourquoi un notify sur un objet doit être appelé
dans un bloc synchronized sur le même objet.
Quelle serait le ou les problèmes si Java n'imposait pas cette restriction.
-
Quelles sont les deux raisons pour lesquels il faut mettre les appels
à wait à l'intérieur d'une boucle while.
-
En s'appuyant sur votre propre expérience, dans quel(les) cas utilise t'on un
java.io.Reader plutôt qu'un java.io.InputStream ?
NB: je ne veux pas ce qu'il y a marqué dans le cours mais que vous répondiez à la question.
-
A quoi sert la méthode tryLock de l'interface
java.util.concurrent.lock.Lock ?
Exercice 2 - Calcul en parallèle
On cherche à effectuer la somme des élements d'un tableau de double en parallèle.
Pour cela, un étudiant n'ayant pas appris son cours produit le code suivant:
static double sum(double[] array, int start, int end) {
double sum = 0.0;
for(int i = start; i < end; i++) {
sum += array[i];
}
return sum;
}
public static double concurrentSum(int numberOfThread, final double[] array) {
int pos = 0;
int length = array.length/ numberOfThread;
final double[] result = new double[numberOfThread];
Thread[] threads = new Thread[numberOfThread];
for(int i=0; i < numberOfThread; i++) {
final int threadIndex = i;
final int start = pos;
final int end = (i == numberOfThread - 1)? array.length: pos + length;
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
result[threadIndex] = sum(array, start, end);
}
});
threads[threadIndex] = thread;
thread.start();
pos = end;
}
return sum(result, 0, result.length);
}
-
Rappeler ce qu'est une race-condition.
Pourquoi il y a une race-condition dans le code ci-dessus.
-
Modifier le code pour que celui-ci soit juste sachant que
l'on vous demande de faire le moins de modifications possibles.
On ne vous demande pas d'utiliser un executor ici (cf question suivante)
-
Indiquer ce que l'on doit changer dans le code ci-dessus pour utiliser
un executor plutôt que de créer les threads à la main.
Le code devra aussi être libre de race-condition.
Exercice 3 - Buffer bloquant
Le code suivant fourni d'une Queue FIFO sous forme de liste chainée.
L'opération put permet d'ajouter un élement à la fin de la liste,
l'opération take retire un élement à la tête de la liste.
On souhaite modifier cette implamntation pour pouvoir l'utiliser
en tant que buffer d'un schéma producteur/consommateur.
public class BlockingLinkedBuffer<E> {
static class Link<E> {
final E element;
Link<E> next;
public Link(E element) {
this.element = element;
}
}
private Link<E> head;
private Link<E> tail;
public void put(E element) {
Link<E> link = new Link<E>(element);
if (head == null) {
head = link;
} else {
tail.next = link;
}
tail = link;
}
public E take() {
if (head == null)
throw new IllegalStateException("buffer is empty");
Link<E> link = head;
if (link.next == null) {
tail = null;
}
head = link.next;
return link.element;
}
}
-
Rappeler qu'elle est le nom de l'interface définissant les
opérations de base sur les buffers producteur/consommateur
en Java.
Note: par la suite nous ne l'utiliseront pas, c'est juste
une question de cours.
-
Rappeler pourquoi dans un schéma producteur/consommateur
le buffer doit bloquer la thread appelante si il
n'y a pas d'élement dans le buffer plutôt que de
renvoyer une exception comme dans le code ci-dessus.
-
Pourquoi doit-on aussi bloquer une thread si il y a plus
d'élements dans le buffer qu'un nombre fixé à l'avance ?
-
Indiquer le code d'un buffer producteur/consommateur
en ré-utilisant la partie algorithmique de la classe ci-dessus,
bloquant les threads des producteurs/consommateur quand il faut
sachant que le nombre maximal d'élément sera 500.
(vous pouvez mettre le chiffre en dure, ce n'est pas cela qui
m'intéresse).
Vous devrez utiliser les verrous (Lock) pour répondre à ce
problème (cf question suivante).
-
Au lieu de bloquer une thread essayant de retirer un élement
dans une Queue vide; Il est préférable si l machine faisant tourner
le prgramme possède plusieurs processeurs de ne pas bloquer la
thread tout de suite mais de tester activement la condition.
On appel ce genre de code spin-lock, au lieu de mettre le verrou
en attente, on va tester la condition dans un boucle car
comme il y a plusieurs processeurs, une thread tournant sur un autre
processeur peu ajouter des élements entre deux tests.
Indiquer un code permettant de faire un spin-lock dans le cas
ou la Queue est vide sachant que l'on fera le test au maximum
100 foix (pareil la constante peut être en dure).
© Université de Marne-la-Vallée