Question

J'ai un morceau de code que je passe en revue (en utilisant 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;

}

Quand je lance FindBugs sur ce morceau de code, il se plaint que -

  

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

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

  

Cette méthode appelle Object.notify () ou   Object.notifyAll () sans évidemment   maintenir un verrou sur l'objet. Appel   notifier () ou notifyAll () sans une serrure   tenue entraînera une   IllegalMonitorStateException étant   jeté

Comment puis-je mettre en œuvre cette méthode pour qu'il passe la validation FindBugs? La mise en œuvre en haut à droite une pour la notification dans les cas pour les classes simultanées?

Merci.

Était-ce utile?

La solution

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

BlockingQueue utilise des mécanismes internes pour bloquer sur un put() s'il n'y a pas d'espace pour plusieurs éléments ou sur poll() s'il n'y a aucun élément à consommer. Vous ne devez pas se soucier de cela.

Autres conseils

La première erreur est indiquant que vous ne devriez pas utiliser des contrôles de synchronisation primitives sur les classes de java.util.concurrent (comme BlockingQueue).

En général, cela est une bonne pratique car ils prennent en charge la synchronisation pour vous. J'imagine qu'il ya une meilleure façon de résoudre votre problème à portée de main. 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 verrouillage / moniteur d'un objet (par sychronizing dessus) pour appeler wait / informer / notifyAll sur elle

BlockingQueue est un synchroniseur - objet coordonne le flux de contrôle de fils à base de son état et ainsi contrôler le débit de fils producteurs / consommateurs car prendre et mettre bloc jusqu'à ce que la file d'attente passe à l'état souhaité (non vide ou non complète).

Aussi bonnes pratiques dans la programmation suppose que la concurrence attente et de notification sont placés dans la boucle while.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top