ejemplo - ¿java BlockingQueue no tiene un vistazo de bloqueo?
blockingqueue java ejemplo (7)
Sin embargo, como no sé si podré procesar el objeto con éxito, solo quiero mirar () y no eliminar el objeto. Quiero eliminar el objeto solo si puedo procesarlo correctamente.
En general, no es seguro para subprocesos. ¿Qué pasaría si, después de peek()
y determinar que el objeto se puede procesar correctamente, pero antes de take()
para eliminarlo y procesarlo, otro subproceso toma ese objeto?
Tengo una cola de bloqueo de objetos.
Quiero escribir un hilo que bloquee hasta que haya un objeto en la cola. Similar a la funcionalidad provista por BlockingQueue.take ().
Sin embargo, como no sé si podré procesar el objeto con éxito, solo quiero mirar () y no eliminar el objeto. Quiero eliminar el objeto solo si puedo procesarlo correctamente.
Por lo tanto, me gustaría una función peek () de bloqueo. Actualmente, peek () simplemente devuelve si la cola está vacía según los javadocs.
¿Me estoy perdiendo de algo? ¿Hay otra manera de lograr esta funcionalidad?
EDITAR:
¿Alguna idea sobre si acabo de usar una cola segura de hilos y miré y dormí en su lugar?
public void run() {
while (!__exit) {
while (__queue.size() != 0) {
Object o = __queue.peek();
if (o != null) {
if (consume(o) == true) {
__queue.remove();
} else {
Thread.sleep(10000); //need to backoff (60s) and try again
}
}
}
Thread.sleep(1000); //wait 1s for object on queue
}
}
Tenga en cuenta que solo tengo un subproceso de consumidor y un subproceso de productor (separado). Supongo que esto no es tan eficiente como usar un BlockingQueue ... Cualquier comentario apreciado.
¿Podría simplemente agregar una cola de escucha de eventos a su cola de bloqueo, luego, cuando se agregue algo a la cola (de bloqueo), enviar un evento a sus oyentes? Podrías tener tu bloque de hilos hasta que se llame al método actionPerformed.
La respuesta rápida es que no hay una manera de tener una vista de bloqueo, la barra implementa una cola de bloqueo con una vista de bloqueo ().
¿Me estoy perdiendo de algo?
peek () puede ser problemático con la concurrencia -
- Si no puede procesar su mensaje peek (), quedará en la cola, a menos que tenga varios consumidores.
- ¿Quién va a sacar ese objeto de la cola si no puede procesarlo?
- Si tienes varios consumidores, obtienes una condición de carrera entre tu peek () ''ing y otra hebra que también procesa artículos, lo que resulta en un procesamiento duplicado o peor.
Suena como si estuvieras mejor eliminando el artículo y procesándolo usando un patrón de Cadena de responsabilidad
Edite: re: su último ejemplo: si solo tiene 1 consumidor, nunca podrá deshacerse del objeto en la cola, a menos que se actualice mientras tanto, en cuyo caso será mejor que tenga mucho cuidado con la seguridad de los hilos y Probablemente no debería haber puesto el artículo en la cola de todos modos.
Lo único que sé es que hace esto en BlockingBuffer en las colecciones de Apache Commons :
Si se llama a obtener o eliminar en un búfer vacío, el subproceso de llamada espera la notificación de que se ha completado una operación agregar o agregar todo.
get()
es equivalente a peek()
, y se puede hacer que un Buffer
actúe como BlockingQueue
decorando UnboundedFifoBuffer con un Buffer
BlockingBuffer
No es una respuesta en sí, pero: JDK-6653412 afirma que este no es un caso de uso válido.
Parece que BlockingQueue en sí no tiene la funcionalidad que estás especificando.
Sin embargo, podría intentar volver a encuadrar el problema un poco: ¿qué harías con los objetos que no puedes "procesar correctamente"? Si solo los dejas en la cola, tendrás que sacarlos en algún momento y lidiar con ellos. Yo recomendaría descubrir cómo procesarlos (comúnmente, si un queue.get () proporciona algún tipo de valor inválido o incorrecto, probablemente esté bien si lo deja caer en el piso) o elegir una estructura de datos diferente a la un FIFO.
Podría usar un LinkedBlockingDeque y eliminar físicamente el elemento de la cola (con takeLast()
), pero reemplazarlo nuevamente al final de la cola si el procesamiento falla usando putLast(E e)
. Mientras tanto, sus "productores" agregarían elementos al frente de la cola usando putFirst(E e)
.
Siempre podría encapsular este comportamiento dentro de su propia implementación de Queue
y proporcionar un método de blockingPeek()
que realice takeLast()
seguido de putLast()
detrás de escena en el LinkedBlockingDeque
subyacente. Por lo tanto, desde la perspectiva del cliente llamante, el elemento nunca se elimina de la cola.