Utilisation réelle de DelayQueue [fermé]


18

Quelle serait une utilisation réelle de DelayQueue , quel problème courant a-t-il été conçu pour résoudre?

Réponses:


8

J'ai récemment utilisé une file d'attente de retard pour limiter le débit.

Pour une limite de X événements par seconde, placez chaque événement dans une file d'attente de retard avec un retard de 1 seconde.

S'il y a X événements sur le delayQueue, prenez () de la file d'attente (qui bloque jusqu'à ce qu'au moins 1 expire). De cette façon, vous autorisez une rafale à court terme, sans dépasser les limites à long terme.


10

Cette classe est parfaite pour un thread qui souhaite traiter plusieurs événements retardés dans leur ordre correct.

Supposons, par exemple, que vous ayez un écran avec 100 voyants clignotants et que tous les voyants clignotent à des vitesses différentes sans rapport. Vous pouvez avoir un fil pour chaque lumière, ou vous pouvez avoir un fil coordonné tous en utilisant cette classe. Cela fonctionnerait quelque chose comme ceci:

  • avoir une Lightclasse avec un taux de flash
  • créer une implémentation de l' Delayedinterface qui pointe vers la lumière, par exempleLightFlash
  • créez votre DelayQueueet ajoutez un nouveau LightFlashpour chaque lumière, avec le délai réglé en fonction du taux de flash de la lumière
  • boucle:

DelayQueue s'occupe de traiter le prochain événement.

Deux exemples concrets auxquels je peux penser:

  • Un serveur (non multithread) qui doit effectuer certaines actions chronométrées, par exemple une connexion ping sur chaque connexion.
  • Une implémentation d'un navigateur compatible javascript, qui doit gérer le nombre arbitraire d'événements chronométrés créés avec setInterval () et setTimeout () . Oh, et des GIF animés.

DelayQueueest probablement implémenté comme une file d'attente prioritaire , qui est généralement mieux implémenté comme un tas .


3

l'utilisation principale serait des minuteurs de tâches comme les classes Timer

si l'on pouvait rendre le retard indépendant de l'horloge système (ce que je crois que vous pouvez, vous n'êtes pas sûr), vous pouvez l'utiliser pour des événements de jeu comme "après que 5 ticks se déplacent vers X" (sinon la gigue d'horloge rendrait cela peu fiable)


2

Notez que les retards sont associés aux éléments qui vont dans la file d'attente plutôt qu'à la file d'attente elle-même. Certains objets qui entrent dans la file d'attente peuvent avoir un délai de zéro, tandis que certains peuvent avoir un délai beaucoup plus long:

http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Delayed.html

Dans cet esprit, je peux penser à quelques cas d'utilisation - bien qu'ils soient probablement fragiles et une odeur de code en ce qui concerne votre flux de messagerie. J'utiliserais des alternatives à tous sauf dans des situations spécifiques:

1) Contrôler le flux - nous savons qu'une commande prend 60 secondes à traiter, alors ne lisez pas la prochaine commande hors de la file d'attente jusqu'à ce que l'objet soit là depuis au moins 60 secondes.

2) Flux de messages - Un système hautement asynchrone où nous envoyons des demandes à 2 ou 3 services externes, puis libérons la tâche suivante pour traiter la commande N secondes plus tard une fois que nous savons que le premier lot de travaux aura au moins eu une chance de se terminer .

3) Traitement par lots des messages - peut-être que les commandes d'un certain type sont en rafale, donc ne permet pas de traiter les commandes reçues dans les N dernières secondes afin que nous puissions voir si des commandes similaires arrivent peu de temps après qui peuvent être traitées comme un lot lors de la prochaine exécution.

4) Priorités des messages - différents messages ou différents clients peuvent obtenir une qualité de service légèrement supérieure avec un délai inférieur ou nul.


1

Dans certains cas, les objets que vous placez dans une file d'attente doivent se trouver dans cette file d'attente pendant un certain temps avant d'être prêts à être retirés de la file d'attente. C'est là que vous utilisez la classe java.util.concurrent.DelayQueue, qui implémente l'interface BlockingQueue. DelayQueue nécessite que les objets de file d'attente résident sur la file d'attente pendant une durée spécifiée.

Pour un exemple d'utilisation dans le monde réel, voir l' article Minding the Queue sur le site devx

... L'exemple du monde réel auquel j'ai pensé pour illustrer cela (qui pourrait vous donner faim) concerne les muffins. Eh bien, les objets Muffin (comme nous parlons de Java - sans jeu de mots). Supposons que vous ayez une DelayQueue sur laquelle vous placez des objets Muffin ... La méthode getDelay, en substance, indique combien de temps il reste pour que l'objet soit conservé dans la DelayQueue. Lorsque le nombre renvoyé par cette méthode devient zéro ou inférieur à zéro, l'objet est prêt (ou dans cet exemple, cuit) et autorisé à être retiré de la file d'attente ...

Puisque vous ne voulez pas vraiment manger un muffin qui n'est pas entièrement cuit, placez le muffin sur la DelayQueue pour le temps de cuisson recommandé ...


1
Je comprends ce qu'il fait, mais pas quel problème courant il a été conçu pour résoudre, je recherche le (s) cas d'utilisation
Eran Medan
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.