Qual seria o uso do DelayQueue no mundo real , que problema comum ele foi projetado para resolver?
Qual seria o uso do DelayQueue no mundo real , que problema comum ele foi projetado para resolver?
Respostas:
Recentemente, usei uma fila de atraso para limitar a taxa.
Para um limite de X eventos por segundo, coloque cada evento em uma fila de atraso com um atraso de 1 segundo.
Se houver X eventos no delayQueue, retire () da fila (que bloqueia até que pelo menos 1 expire). Dessa forma, você permite uma explosão de curto prazo, sem exceder os limites de longo prazo.
Essa classe é perfeita para um encadeamento que deseja processar vários eventos atrasados na ordem correta.
Suponha, por exemplo, que você tenha uma tela com 100 luzes piscando e todas as luzes pisquem em taxas diferentes. Você pode ter um encadeamento para cada luz ou coordenar um encadeamento todos eles usando esta classe. Funcionaria algo como isto:
Light
aula com uma taxa de flashDelayed
interface que aponte para a luz, digamosLightFlash
DelayQueue
e adicione um novo LightFlash
para cada luz, com o atraso definido apropriado para a taxa de flash da luzDelayQueue se encarrega de obter o próximo evento para processar.
Dois exemplos do mundo real em que posso pensar:
DelayQueue
provavelmente é implementado como uma fila de prioridade , que geralmente é melhor implementada como um heap .
o uso principal seria temporizadores de tarefas como o das classes Timer
se alguém puder tornar o atraso independente do relógio do sistema (que eu acredito que você pode, não tenho certeza), você pode usá-lo para eventos de jogos como "após 5 ticks passarem para X" (caso contrário, o jitter do relógio torna isso não confiável)
Observe que os atrasos estão associados aos elementos que entram na fila e não na própria fila. Alguns objetos que entram na fila podem ter um atraso zero, enquanto outros podem ter um atraso muito maior:
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Delayed.html
Com isso em mente, posso pensar em alguns casos de uso - embora provavelmente sejam frágeis e cheiram um pouco ao código com relação ao seu fluxo de mensagens. Eu usaria alternativas para todos eles, exceto em situações específicas:
1) Fluxo de controle - sabemos que um pedido leva 60 segundos para processar; portanto, não leia o próximo pedido da fila até que o objeto esteja lá por pelo menos 60 segundos.
2) Fluxo de mensagens - Um sistema altamente assíncrono em que enviamos solicitações para 2 ou 3 serviços externos e liberamos a próxima tarefa para processar o pedido N segundos depois, uma vez que sabemos que o primeiro lote de tarefas terá pelo menos uma chance de concluir .
3) Lote de mensagens - talvez pedidos de um determinado tipo estejam com problemas, portanto, não processemos pedidos recebidos nos últimos N segundos, para que possamos ver se pedidos semelhantes chegam logo depois que podem ser processados como um lote na próxima execução.
4) Prioridades das mensagens - mensagens diferentes ou clientes diferentes podem obter uma qualidade de serviço um pouco mais alta com um atraso menor ou zero.
Em alguns casos, os objetos que você coloca em uma fila devem permanecer nessa fila por um determinado período de tempo antes de estarem prontos para serem desenfileirados. É aqui que você usa a classe java.util.concurrent.DelayQueue, que implementa a interface BlockingQueue. O DelayQueue exige que os objetos da fila permaneçam na fila por um período de tempo especificado.
Para obter exemplos de uso no mundo real, consulte o artigo Minding the Queue no site devx
... O exemplo do mundo real que pensei em ilustrar isso (o que pode deixá-lo com fome) envolve muffins. Bem, objetos Muffin (como estamos falando de Java - sem trocadilhos de café). Suponha que você tenha um DelayQueue no qual você coloca objetos Muffin ... O método getDelay, em essência, indica quanto tempo resta para o objeto ser mantido no DelayQueue. Quando o número retornado por este método se torna zero ou menor que zero, o objeto está pronto (ou, neste exemplo, cozido) e pode ser retirado da fila ...
Como você realmente não quer comer um Muffin que não esteja totalmente cozido, coloque o Muffin no DelayQueue pelo tempo recomendado para cozinhar ...