BoundedSafeQueue
public class BoundedSafeQueue<V> {
private final ArrayDeque<V> queue = new ArrayDeque<>();
private final int capacity;
...
public void add(V value) throws InterruptedException {
Objects.requireNonNull(value);
synchronized (queue) {
while (queue.size() >= capacity) {
queue.wait();
}
queue.add(value);
queue.notify();
}
}
public V take() throws InterruptedException {
synchronized (queue) {
while (queue.isEmpty()) {
queue.wait();
}
queue.notify();
return queue.remove();
}
}
Quel est le problème?
Supposons que 2 threads nommés t1 et t2 font des add et qu'un 3e thread, le main, fait des take, en continu, sur une file de capacité 1.
public class BoundedSafeQueue<V> {
private final ArrayDeque<V> queue = new ArrayDeque<>();
private final int capacity;
...
public void add(V value) throws InterruptedException {
Objects.requireNonNull(value);
synchronized (queue) {
while (queue.size() >= capacity) {
queue.wait();
}
queue.add(value);
queue.notifyAll();
}
}
public V take() throws InterruptedException {
synchronized (queue) {
while (queue.isEmpty()) {
queue.wait();
}
queue.notifyAll();
return queue.remove();
}
}
main.On veut une classe thread-safe pour faire un vote. Quand n votes ont été enregistrés, on renvoie à chaque votant la String qui a reçu le plus de votes.
vote qui sert à proposer son vote et qui bloque jusqu'à ce que les n votes soient arrivés ; elle renvoie le gagnant.
vote est appelée après que les n votes aient été reçus, la méthode renvoie simplement le gagnant.
Principaux problèmes constatés :
wait notifie tous les autres.
Pour l'instant, nous ne gérons pas les InteruptedException et rien dans votre code ne peut provoquer la levée de cette exception.
throws),
Runnable run = () -> {
try {
Thread.sleep(20_000);
} catch (InterruptedException e) {
// this should not happen !
throw new AssertionError(e);
}
};
On ne doit jamais voir e.printStackTrace();