Verwendung von DelayQueue in der realen Welt [geschlossen]

18

Was wäre ein Einsatz von DelayQueue in der realen Welt , welches häufige Problem sollte damit gelöst werden?

Eran Medan
quelle

Antworten:

8

Ich habe kürzlich eine Verzögerungswarteschlange zur Ratenbegrenzung verwendet.

Platzieren Sie für ein Limit von X Ereignissen pro Sekunde jedes Ereignis mit einer Verzögerung von 1 Sekunde in einer Verzögerungswarteschlange.

Wenn die delayQueue X Ereignisse enthält, nehmen Sie () aus der Warteschlange (die blockiert, bis mindestens 1 abläuft). Auf diese Weise können Sie einen kurzfristigen Burst zulassen, ohne langfristige Grenzwerte zu überschreiten.

Andrew Hill
quelle
10

Diese Klasse ist perfekt für einen Thread, der mehrere verzögerte Ereignisse in der richtigen Reihenfolge verarbeiten möchte.

Angenommen, Sie haben ein Display mit 100 blinkenden Lichtern und alle Lichter blinken mit unterschiedlichen, unabhängigen Raten. Sie könnten einen Thread für jedes Licht haben, oder Sie könnten einen Thread haben, der alle mit dieser Klasse koordiniert. Es würde ungefähr so ​​funktionieren:

  • habe eine LightKlasse mit einer Blitzrate
  • Erstellen Sie eine Implementierung der DelayedSchnittstelle, die beispielsweise auf das Licht verweistLightFlash
  • Erstellen Sie Ihre DelayQueueund fügen Sie LightFlashfür jedes Licht eine neue hinzu , wobei die Verzögerung auf die Blitzrate des Lichts abgestimmt ist
  • Schleife:

DelayQueue sorgt dafür, dass das nächste Ereignis verarbeitet wird.

Zwei Beispiele aus der Praxis, die mir einfallen:

  • Ein (Nicht-Multithread-) Server, der bestimmte zeitgesteuerte Aktionen ausführen muss, z. B. Verbindungs-Ping für jede Verbindung.
  • Eine Implementierung eines JavaScript-fähigen Browsers, der die beliebige Anzahl von zeitgesteuerten Ereignissen verarbeiten muss, die mit setInterval () und setTimeout () erstellt wurden . Oh, und animierte GIFs.

DelayQueuewird wahrscheinlich als Prioritätswarteschlange implementiert , die im Allgemeinen am besten als Heap implementiert wird .

Michael Slade
quelle
3

Die Hauptverwendung wären Task-Timer wie die für Timer-Klassen

Wenn man die Verzögerung von der Systemuhr unabhängig machen könnte (was ich glaube, aber nicht sicher bin), kann man sie für Spielereignisse wie "Nach 5 Ticks auf X verschieben" verwenden (andernfalls würde Clock Jitter dies unzuverlässig machen).

Ratschenfreak
quelle
2

Beachten Sie, dass die Verzögerungen eher mit den Elementen in der Warteschlange als mit der Warteschlange selbst verknüpft sind. Einige Objekte, die in die Warteschlange gestellt werden, können eine Verzögerung von Null aufweisen, während andere eine wesentlich längere Verzögerung aufweisen können:

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

In diesem Sinne kann ich mir einige Anwendungsfälle vorstellen - obwohl sie wahrscheinlich zerbrechlich sind und in Bezug auf Ihren Nachrichtenfluss ein bisschen nach Code riechen. Ich würde Alternativen zu allen verwenden, außer in bestimmten Situationen:

1) Kontrollfluss - Wir wissen, dass die Verarbeitung eines Auftrags 60 Sekunden dauert. Lesen Sie daher den nächsten Auftrag erst aus der Warteschlange, wenn das Objekt mindestens 60 Sekunden dort war.

2) Nachrichtenfluss - Ein stark asynchrones System, bei dem wir Anfragen an zwei oder drei externe Dienste senden und dann die nächste Aufgabe freigeben, um den Auftrag N Sekunden später zu verarbeiten, sobald wir wissen, dass der erste Stapel von Aufträgen zumindest die Chance hat, abgeschlossen zu werden .

3) Stapelverarbeitung von Nachrichten - Möglicherweise sind Aufträge eines bestimmten Typs unvollständig, sodass Aufträge, die in den letzten N Sekunden eingegangen sind, nicht verarbeitet werden können. So können wir feststellen, ob ähnliche Aufträge kurz darauf eingehen und beim nächsten Durchlauf als Stapel verarbeitet werden können.

4) Nachrichtenprioritäten - Unterschiedliche Nachrichten oder unterschiedliche Kunden können eine geringfügig höhere Dienstqualität mit einer geringeren oder nullten Verzögerung erzielen.

Benjamin Wootton
quelle
1

In einigen Fällen sollten sich Objekte, die Sie in eine Warteschlange stellen, eine bestimmte Zeit lang in dieser Warteschlange befinden, bevor sie in die Warteschlange gestellt werden können. Hier verwenden Sie die Klasse java.util.concurrent.DelayQueue, die die BlockingQueue-Schnittstelle implementiert. Für die DelayQueue müssen sich die Warteschlangenobjekte eine bestimmte Zeit lang in der Warteschlange befinden.

Ein Beispiel für die Verwendung in der Praxis finden Sie im Artikel Warteschlange bearbeiten auf der devx-Site

... Das reale Beispiel, an dem ich dachte, um dies zu veranschaulichen (was Sie hungrig machen könnte), beinhaltet Muffins. Nun, Muffin-Objekte (während wir über Java sprechen - kein Kaffee-Wortspiel beabsichtigt). Angenommen, Sie haben eine DelayQueue, auf der Sie Muffin-Objekte platzieren ... Die Methode getDelay gibt im Wesentlichen an, wie viel Zeit für die Aufbewahrung des Objekts in der DelayQueue verbleibt. Wenn die von dieser Methode zurückgegebene Zahl Null oder kleiner als Null ist, ist das Objekt bereit (oder in diesem Beispiel gebacken) und kann aus der Warteschlange entfernt werden.

Da Sie nicht wirklich ein Muffin essen möchten, das noch nicht vollständig gekocht ist, legen Sie das Muffin für die empfohlene Garzeit auf die DelayQueue ...

Shree
quelle
1
Ich verstehe, was es tut, aber nicht, welches häufige Problem es lösen sollte, ich suche nach den Anwendungsfällen
Eran Medan