Pregunta

El título de esta pregunta me hace dudar si esto existe, pero aún así:

Estoy interesado en saber si hay una implementación de Java BlockingQueue , que está limitado por el tamaño y nunca bloquea, sino que arroja una excepción cuando se intenta poner en cola demasiados elementos.

Editar : estoy pasando el BlockingQueue a un Ejecutor, que supongo que usa su método add (), no offer (). Uno puede escribir un BlockingQueue que envuelva otro BlockingQueue y delegue llamadas para agregar () a ofrecer ().

¿Fue útil?

Solución

Editar: según su nueva descripción, creo que está haciendo la pregunta incorrecta. Si está utilizando un ejecutor, probablemente debería definir un RejectedExecutionHandler en lugar de modificar la cola. Esto solo funciona si está utilizando un ThreadPoolExecutor, pero si no lo está, probablemente sería una mejor idea modificar el Ejecutor en lugar de la cola.

Es mi opinión que es un error anular la oferta y hacer que se comporte como agregar. Los métodos de interfaz constituyen un contrato. El código del cliente que usa colas de bloqueo depende de los métodos que realmente hacen lo que especifica la documentación. Romper esa regla se abre para un mundo de dolor. Eso, y es poco elegante.


El agregar () en BlockingQueues lo hace, pero también tienen un offer () que generalmente es una mejor opción. De la documentación para la oferta ():

  

Inserta el elemento especificado en el   cola de esta cola si es posible   hacerlo inmediatamente sin exceder   la capacidad de la cola, volviendo verdadera   en caso de éxito y falso si esta cola   está lleno. Este método es generalmente   preferible al método add (E), que puede   no puede insertar un elemento solo por   lanzando una excepción.

Esto funciona para todas esas colas independientemente de la implementación específica (ArrayBlockingQueue, LinkedBlockingQueue, etc.)

BlockingQueue<String> q = new LinkedBlockingQueue<String>(2);
System.out.println(q.offer("foo")); // true
System.out.println(q.offer("bar")); // true
System.out.println(q.offer("baz")); // false

Otros consejos

  

Uno puede escribir un BlockingQueue que   envuelve otro BlockingQueue y   delega llamadas para agregar () a ofrecer ().

Si se supone que es una pregunta ... la respuesta es "Sí", pero puede hacerlo de manera más clara creando una subclase que anule la suma (). El único inconveniente (en ambos casos) es que su versión de add no puede lanzar ninguna excepción marcada que no esté en el método que está anulando, por lo que su " bloquearía " la excepción deberá estar desmarcada.

esto es triste, no puede bloquear, hay tantos casos de uso en los que desea bloquear, que la idea de proporcionar su propia cola de bloqueo limitada al ejecutor no tiene sentido.

public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        if (poolSize >= corePoolSize || !addIfUnderCorePoolSize(command)) {
            if (runState == RUNNING && workQueue.***offer***(command)) {
                if (runState != RUNNING || poolSize == 0)
                    ensureQueuedTaskHandled(command);
            }
            else if (!addIfUnderMaximumPoolSize(command))
                reject(command); // is shutdown or saturated
        }
    }

Un caso de uso simple para obtener consultas ejecutadas desde la fuente db en lote (ejecutor), enriquecer en lote y poner en otra db (ejecutor), desearía ejecutar consultas solo tan rápido como se ponen en otra base de datos. En ese caso, el ejecutor de destino debe aceptar un ejecutor acotado de bloqueo para resolver el problema que seguir encuestando y verificando cuántos se completaron para ejecutar más consultas.

uy más, mira mi comentario restante:

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