2 votes

Synchronisation sur BlockedQueue

J'ai un morceau de code que je suis en train d'examiner (à l'aide de FindBugs ).

public class MyClass{
...
private BlockedQueue q = new LinkedBlockingQueue<MyData>(1000);
private static final batchSize = 1000;

public boolean testMethod(){
    boolean done = false;
    synchronized(q){
       if(q.size == batchSize){
         q.notify();
         done = true;
       }
    }
    return done;

}

Lorsque j'exécute FindBugs sur ce morceau de code, il se plaint que -

Cette méthode réalise la synchronisation d'un objet qui est une instance d'une classe du paquet java.util.concurrent (ou ses sous-classes). Les instances de ces classes ont leur propre méthode mécanismes de contrôle de la concurrence qui qui sont distincts de et incompatibles avec l'utilisation du mot-clé synchronisé.

Si je commente le morceau de code synchronisé synchronized(q){ il se plaint -

Cette méthode appelle Object.notify() ou [ ] détenir un verrou sur l'objet. L'appel à notify() ou notifyAll() sans que le verrou ne soit détenu, il en résultera un IllegalMonitorStateException étant lancée à l'adresse

Comment implémenter cette méthode pour qu'elle passe la validation de FindBugs ? L'implémentation ci-dessus est-elle la bonne pour la notification dans les cas de classes concurrentes ?

Merci.

3voto

tangens Points 17733

notify() va de pair avec wait() et ne doit pas être utilisé avec les classes de java.util.concurrent .

BlockingQueue utilise des mécanismes internes pour bloquer sur une put() s'il n'y a pas de place pour d'autres éléments ou sur poll() s'il n'y a pas d'élément à consommer. Il n'est pas nécessaire de s'en préoccuper.

0voto

Kevin Points 19613

La première erreur indique que vous ne devez pas utiliser les contrôles de synchronisation primitifs sur les classes java.util.concurrentes (comme BlockingQueue).

En général, c'est une bonne pratique car ils se chargent de la synchronisation pour vous. J'imagine qu'il existe une meilleure façon de résoudre votre problème. Quel est le problème réel que vous essayez de résoudre ?

La deuxième erreur est causée par le fait que vous DEVEZ posséder le verrou/moniteur d'un objet (en vous synchronisant dessus) pour appeler wait/notify/notifyAll sur cet objet.

0voto

Ovidiu Lupas Points 103

BlockingQueue est une syncroniseur coordonne le flux de contrôle des threads en fonction de son état et donc le flux de contrôle des threads producteurs/consommateurs car prendre y mettre bloquent jusqu'à ce que la file d'attente atteigne l'état souhaité (non vide ou non pleine).

De même, les bonnes pratiques en matière de programmation concurrentielle supposent que wait et notify soient placés dans la boucle while.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X