Pergunta

O título desta pergunta me faz duvidar se isso existe, mas ainda assim:

Estou interessado em se há um implementado de Java's BlockingQueue, isso é delimitado pelo tamanho e nunca bloqueia, mas sim uma exceção ao tentar envolver muitos elementos.

Editar - Estou passando o BlockingQueue para um executor, que suponho que use seu método add (), não ofereça (). Pode -se escrever um BlockingQueue que envolve outro blockingqueue e delegados chamadas para adicionar () para oferecer ().

Foi útil?

Solução

Editar: Com base na sua nova descrição, acredito que você está fazendo a pergunta errada. Se você estiver usando um executor, provavelmente deve definir um costume RejeitEdExecutionHandler em vez de modificar a fila. Isso só funciona se você estiver usando um ThreadpoolExecutor, mas se você não for, provavelmente seria uma idéia melhor modificar o executor em vez da fila.

É minha opinião que é um erro substituir a oferta e fazê -la se comportar como add. Os métodos de interface constituem um contrato. O código do cliente que usa filas de bloqueio depende dos métodos que realmente fazem o que a documentação especifica. Quebrar essa regra se abre para um mundo de mágoa. Isso, e é deselegante.


o adicionar() Método em BlockingQueues faz isso, mas eles também têm um oferta() Método que geralmente é uma escolha melhor. Da documentação para oferta ():

Insira o elemento especificado na cauda desta fila, se for possível fazê -lo imediatamente sem exceder a capacidade da fila, retornando verdadeiro sobre o sucesso e o falso se essa fila estiver cheia. Esse método é geralmente preferível ao método add (e), que pode deixar de inserir um elemento apenas lançando uma exceção.

Isso funciona para todas essas filas, independentemente da implementação específica (ArrayBlockingQueue, LinkedBlockingQuee 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

Outras dicas

Pode -se escrever um BlockingQueue que envolve outro blockingqueue e delegados chamadas para adicionar () para oferecer ().

Se isso deve ser uma pergunta ... a resposta é "sim", mas você pode fazê -lo de maneira mais ordenada criando uma subclasse que substitui o add (). A única captura (em ambos os casos) é que sua versão de add Não é possível lançar exceções verificadas que não estão no método que você está substituindo; portanto, sua exceção "bloqueará" precisará ser desmarcada.

Isso é triste, você não pode bloquear, há tantos casos de uso em que você deseja bloquear, toda a idéia de fornecer sua própria fila de bloqueio limitado ao executor não tem significado.

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
        }
    }

Um caso de uso simples para obter consultas executadas a partir do DB de origem no lote (executor), enriquecer em lote e colocar em outro banco de dados (executor), você deseja executar consultas apenas tão rápido quanto elas estão sendo colocadas em outro banco de dados. Nesse caso, o Executor do Dest deve aceitar um executor limitado de bloqueio para resolver o problema do que continuar pesquisando e verificando quantos foram concluídos para executar mais consultas.

opa mais, veja meu comentário restante:

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top