Sincronizar en BlockedQueue
-
21-09-2019 - |
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.
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.