Quale sarebbe un uso reale di DelayQueue , quale problema comune è stato progettato per risolvere?
Quale sarebbe un uso reale di DelayQueue , quale problema comune è stato progettato per risolvere?
Risposte:
Di recente ho usato una coda di ritardo per limitare la velocità.
Per un limite di X eventi al secondo, posizionare ogni evento in una coda di ritardo con un ritardo di 1 secondo.
Se ci sono eventi X su delayQueue, prendere () dalla coda (che si blocca fino alla scadenza di almeno 1). In questo modo permetti un'esplosione a breve termine, senza superare alcun limite a lungo termine.
Questa classe è perfetta per un thread che desidera elaborare più eventi ritardati nell'ordine corretto.
Supponiamo, ad esempio, che tu abbia un display con 100 luci lampeggianti e tutte le luci lampeggino a frequenze non correlate diverse. Potresti avere un filo per ogni luce, oppure potresti avere un filo coordinare tutti loro usando questa classe. Funzionerebbe qualcosa del genere:
Light
classe con una frequenza di flashDelayed
dell'interfaccia che punta alla luce, diciamoLightFlash
DelayQueue
e aggiungi un nuovo LightFlash
per ogni luce, con il ritardo impostato appropriato per la frequenza di flash della luceDelayQueue si occupa di far elaborare il prossimo evento.
Due esempi reali che mi vengono in mente:
DelayQueue
è probabilmente implementato come una coda prioritaria , che è generalmente meglio implementata come un heap .
l'uso principale sarebbe timer attività come per le classi Timer
se uno potesse rendere il ritardo indipendente dall'orologio di sistema (cosa che credo sia possibile, non sono sicuro) puoi usarlo per eventi di gioco come "dopo 5 tick si sposta su X" (altrimenti il jitter dell'orologio lo renderebbe inaffidabile)
Si noti che i ritardi sono associati agli elementi che vanno nella coda anziché nella coda stessa. Alcuni oggetti che vanno in coda potrebbero avere un ritardo pari a zero, mentre altri possono avere un ritardo molto più lungo:
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Delayed.html
Con questo in mente, posso pensare ad alcuni casi d'uso, anche se probabilmente sarebbero fragili e un po 'di un odore di codice per quanto riguarda il flusso di messaggi. Userei alternative a tutti loro tranne in situazioni specifiche:
1) Flusso di controllo: sappiamo che l'elaborazione di un ordine richiede 60 secondi, quindi non leggere l'ordine successivo fuori dalla coda finché l'oggetto non è stato lì per almeno 60 secondi.
2) Flusso di messaggi: un sistema altamente asincrono in cui inviamo richieste a 2 o 3 servizi esterni e quindi rilasciamo l'attività successiva per elaborare l'ordine N secondi dopo, quando sappiamo che il primo batch di lavori avrà almeno una possibilità di essere completato .
3) Raggruppamento dei messaggi - forse gli ordini di un certo tipo sono in crisi, quindi non evadiamo gli ordini ricevuti negli ultimi N secondi in modo da poter vedere se ordini simili arrivano poco dopo che possono essere elaborati come batch alla prossima esecuzione.
4) Priorità dei messaggi: messaggi diversi o clienti diversi potrebbero ottenere una qualità del servizio leggermente superiore con un ritardo inferiore o nullo.
In alcuni casi, gli oggetti posizionati su una coda devono rimanere su quella coda per un certo periodo di tempo prima di essere pronti per essere rimossi. Qui è dove si utilizza la classe java.util.concurrent.DelayQueue, che implementa l'interfaccia BlockingQueue. DelayQueue richiede che gli oggetti della coda siano residenti sulla coda per un periodo di tempo specificato.
Per un esempio di utilizzo nel mondo reale, consultare l' articolo Minding the Queue sul sito devx
... L'esempio del mondo reale che ho pensato di illustrare questo (che potrebbe farti venire fame) riguarda i muffin. Bene, gli oggetti Muffin (mentre parliamo di Java - nessun gioco di parole inteso per il caffè). Supponiamo di avere un DelayQueue su cui posizionare gli oggetti Muffin ... Il metodo getDelay, in sostanza, indica quanto tempo rimane per l'oggetto da conservare in DelayQueue. Quando il numero restituito da questo metodo diventa zero o inferiore a zero, l'oggetto è pronto (o in questo esempio, cotto) e può essere rimescolato ...
Dal momento che non vuoi davvero mangiare un muffin che non è completamente cotto, posizionalo sul DelayQueue per il tempo di cottura consigliato ...