Una capacidad limitada BlockingQueue
también es útil si desea acelerar algún tipo de solicitud. Con una cola sin límites, los productores pueden adelantarse mucho a los consumidores. Las tareas eventualmente se realizarán (a menos que haya tantas que causen un OutOfMemoryError
), pero el productor puede haberse rendido hace mucho tiempo, por lo que el esfuerzo se desperdicia.
En situaciones como estas, puede ser mejor indicar a un posible productor que la cola está llena y renunciar rápidamente con una falla. Por ejemplo, el productor podría ser una solicitud web, con un usuario que no quiere esperar demasiado, y aunque no consumirá muchos ciclos de CPU mientras espera, está usando recursos limitados como un socket y algo de memoria. . Renunciar dará a las tareas que se han puesto en cola ya una mejor oportunidad de terminar de manera oportuna.
En cuanto a la pregunta modificada, que estoy interpretando como, "¿Qué es una buena colección para sostener objetos en una piscina?"
Un ilimitado LinkedBlockingQueue
es una buena opción para muchas piscinas. Sin embargo, dependiendo de la estrategia de administración de su grupo, también puede funcionar un ConcurrentLinkedQueue
.
En una aplicación de agrupamiento, un "bloqueo" de bloqueo no es apropiado. Controlar el tamaño máximo de la cola es el trabajo del administrador de la agrupación —. Decide cuándo crear o destruir recursos para la agrupación. Los clientes de la agrupación piden prestado y devuelven recursos del grupo. Agregar un nuevo objeto o devolver un objeto previamente prestado al grupo debe ser operaciones rápidas y sin bloqueos. Por lo tanto, una cola de capacidad limitada no es una buena opción para las agrupaciones.
Por otro lado, al recuperar un objeto del grupo, la mayoría de las aplicaciones desean esperar hasta que haya un recurso disponible. Una operación de "toma" que bloquea, al menos temporalmente, es mucho más eficiente que una "espera ocupada" — sondeando varias veces hasta que haya un recurso disponible. El LinkedBlockingQueue
es una buena opción en este caso. Un prestatario puede bloquear indefinidamente con take
o limitar el tiempo que está dispuesto a bloquear con poll
.
Un caso menos común en cuando un cliente no está dispuesto a bloquear en absoluto, sino que tiene la capacidad de crear un recurso por sí mismo si la piscina está vacía. En ese caso, un ConcurrentLinkedQueue
es una buena opción. Esta es una especie de área gris en la que sería bueno compartir un recurso (por ejemplo, memoria) tanto como sea posible, pero la velocidad es aún más importante. En el peor de los casos, esto degenera a cada hilo que tiene su propia instancia del recurso; entonces habría sido más eficiente no molestarse en tratar de compartir entre hilos.
Ambas colecciones proporcionan un buen rendimiento y facilidad de uso en una aplicación simultánea. Para aplicaciones no concurrentes, un ArrayList
es difícil de superar. Incluso para las colecciones que crecen de forma dinámica, la sobrecarga por elemento de un LinkedList
permite una ArrayList
con algunos espacios vacíos para mantenerse en memoria sabia competitiva.
Gracias Erickson para una buena explicación. Ha resuelto mi problema. –