Jakie byłoby rzeczywiste wykorzystanie DelayQueue , jaki typowy problem został rozwiązany?
źródło
Jakie byłoby rzeczywiste wykorzystanie DelayQueue , jaki typowy problem został rozwiązany?
Niedawno użyłem kolejki opóźnień do ograniczenia prędkości.
Aby uzyskać limit X zdarzeń na sekundę, umieść każde zdarzenie w kolejce opóźnień z 1-sekundowym opóźnieniem.
Jeśli na delayQueue znajduje się X zdarzeń, weź () z kolejki (która blokuje się, aż minie co najmniej 1). W ten sposób pozwalasz na krótkotrwały wybuch, nie przekraczając żadnych długoterminowych limitów.
Ta klasa jest idealna dla wątku, który chce przetwarzać wiele opóźnionych zdarzeń we właściwej kolejności.
Załóżmy na przykład, że masz wyświetlacz ze 100 migającymi światłami, a wszystkie światła migają z różnymi niezwiązanymi częstotliwościami. Możesz mieć wątek dla każdego światła lub jeden wątek koordynować wszystkie za pomocą tej klasy. Działa to mniej więcej tak:
Light
klasę z szybkością błyskuDelayed
powiedzmy, stworzyć implementację interfejsu, który wskazuje na światłoLightFlash
DelayQueue
i dodaj nowe LightFlash
dla każdego światła, z ustawionym opóźnieniem odpowiednim dla szybkości błysku światłaDelayQueue zajmuje się przetwarzaniem następnego zdarzenia.
Dwa rzeczywiste przykłady, o których mogę myśleć:
DelayQueue
prawdopodobnie jest zaimplementowany jako kolejka priorytetowa , która generalnie najlepiej jest implementowana jako sterta .
głównym zastosowaniem byłyby timery zadań, takie jak dla klas Timer
jeśli można uniezależnić opóźnienie od zegara systemowego (co, jak sądzę, możesz, nie jestem pewien), możesz użyć go do wydarzeń w grze, takich jak „po 5 tyknięciach przejście do X” (w przeciwnym razie jitter zegara spowodowałby, że jest to niewiarygodne)
Zauważ, że opóźnienia są związane z elementami, które idą w kolejce, a nie samą kolejką. Niektóre obiekty, które trafiają do kolejki, mogą mieć opóźnienie równe zero, a niektóre mogą mieć znacznie dłuższe opóźnienie:
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Delayed.html
Mając to na uwadze, mogę wymyślić kilka przypadków użycia - choć prawdopodobnie byłyby one delikatne i miałyby zapach kodu w odniesieniu do przepływu wiadomości. Użyłbym alternatyw dla nich wszystkich, z wyjątkiem szczególnych sytuacji:
1) Kontrola przepływu - wiemy, że przetworzenie zamówienia zajmuje 60 sekund, więc nie czytaj następnego zamówienia z kolejki, dopóki obiekt nie będzie tam przez co najmniej 60 sekund.
2) Przepływ komunikatów - wysoce asynchroniczny system, w którym wysyłamy żądania do 2 lub 3 usług zewnętrznych, a następnie zwalniamy kolejne zadanie w celu przetworzenia zamówienia N sekund później, gdy wiemy, że pierwsza partia zadań będzie miała co najmniej szansę zrealizowania .
3) Grupowanie wiadomości - być może zamówienia określonego typu są rozerwane, więc nie przetwarzajmy zamówień otrzymanych w ciągu ostatnich N sekund, abyśmy mogli zobaczyć, czy podobne zamówienia pojawią się wkrótce potem i będą mogły być przetwarzane jako partia przy następnym uruchomieniu.
4) Priorytety wiadomości - różne wiadomości lub różni klienci mogą uzyskać nieco wyższą jakość usług z mniejszym lub zerowym opóźnieniem.
W niektórych przypadkach obiekty umieszczone w kolejce powinny znajdować się w tej kolejce przez określony czas, zanim będą gotowe do kolejkowania. Tutaj używasz klasy java.util.concurrent.DelayQueue, która implementuje interfejs BlockingQueue. DelayQueue wymaga, aby obiekty kolejki rezydowały w kolejce przez określony czas.
Przykład użycia w świecie rzeczywistym znajduje się w artykule Minding the Queue na stronie devx
... Przykład z prawdziwego świata, który chciałem to zilustrować (co może sprawić, że będziesz głodny), obejmuje babeczki. Cóż, obiekty Muffin (jak mówimy w Javie - nie zamierzamy używać słów kawowych). Załóżmy, że masz DelayQueue, na którym umieszczasz obiekty Muffin ... Metoda getDelay w istocie określa, ile czasu pozostało do przechowywania obiektu w DelayQueue. Gdy liczba zwracana tą metodą staje się zero lub mniejsza niż zero, obiekt jest gotowy (lub w tym przykładzie upieczony) i pozwala się go usunąć z kolejki ...
Ponieważ tak naprawdę nie chcesz jeść Muffinów, które nie są w pełni ugotowane, umieść Muffiny w DelayQueue na zalecany czas gotowania ...