Pregunta

Tengo un pedazo de código que estoy revisando (usando 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;

}

Cuando corro FindBugs en este pedazo de código, se queja de que -

  

Esta sincronización realiza el método   un objeto que es una instancia de una   clase desde el java.util.concurrent   envase (o sus subclases). Instancias   de estas clases tienen su propio   mecanismos de control de concurrencia que   son distintos de e incompatible   con el uso de la palabra clave   sincronizada.

Si comento hacia fuera la pieza de código sincronizado synchronized(q){, se queja -

  

Este método llama Object.notify () o   Object.notifyAll () sin, obviamente,   que mantiene un bloqueo en el objeto. Vocación   notificar () o notifyAll () sin una cerradura   celebrada dará lugar a una   IllegalMonitorStateException bienestar   tirado

¿Cómo iba yo a poner en práctica este método de forma que pase la validación FindBugs? Es el más adecuado por encima de la aplicación para la notificación de los casos para las clases concurrentes?

Gracias.

¿Fue útil?

Solución

notify() va de la mano con wait() y no debe ser utilizado con clases de java.util.concurrent.

BlockingQueue utiliza mecanismos internos para bloquear en una put() si no hay espacio para más elementos o en poll() si no hay ningún elemento de consumir. Usted no tiene que preocuparse por esto.

Otros consejos

El primer error está diciendo que usted no debe utilizar los controles de sincronización primitivos en clases java.util.concurrent (como BlockingQueue).

En general, esta es una buena práctica, ya que se encargan de la sincronización para usted. Me imagino que hay una mejor manera de resolver el problema en cuestión. ¿Cuál es el problema real que estamos tratando de resolver?

El segundo error es causado por el hecho de que debe poseer el bloqueo / monitor de un objeto (por Sincronización de en él) para llamar a la espera / notificar / notifyAll en él

BlockingQueue es un syncronizer objeto - coordenadas el flujo de control de hilos sobre la base de su estado y, por tanto flujo de control del productor hilos / consumidor porque tomar y put bloque hasta que la cola entra en el estado deseado (no vacía o no completa).

Además de buenas prácticas en la programación de concurrencia asume que espera y notificar se colocan en el bucle while.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top