Sprievodca po PriorityBlockingQueue v Jave

1. Úvod

V tomto článku sa zameriame na Priorita blokovania triedy a preštudujte si niekoľko praktických príkladov.

Počnúc predpokladom, že už vieme, čo a Fronta je, najskôr si ukážeme ako prvky v Priorita blokovania sú zoradené podľa priority.

Potom ukážeme, ako možno tento typ frontu použiť na blokovanie vlákna.

Na záver ukážeme, ako môže byť spoločné použitie týchto dvoch funkcií pri spracovaní údajov vo viacerých vláknach užitočné.

2. Priorita prvkov

Na rozdiel od štandardného radu nemôžete do a len pridať akýkoľvek typ prvku Priorita blokovania. Existujú dve možnosti:

  1. Pridávanie prvkov, ktoré implementujú Porovnateľné
  2. Pridávanie prvkov, ktoré sa neimplementujú Porovnateľné, pod podmienkou, že poskytnete a Komparátor tiež

Použitím buď Komparátor alebo Porovnateľné implementácie na porovnanie prvkov, Priorita blokovania budú vždy zoradené.

Cieľom je implementovať logiku porovnávania spôsobom prvok s najvyššou prioritou je vždy zoradený ako prvý. Keď potom odstránime prvok z nášho poradia, bude to vždy ten s najvyššou prioritou.

Na začiatok využime náš rad v jednom vlákne, na rozdiel od jeho použitia vo viacerých vláknach. Týmto spôsobom uľahčíte preukázanie poradia prvkov v jednotkovom teste:

Fronta PriorityBlockingQueue = nová PriorityBlockingQueue (); ArrayList polledElements = nový ArrayList (); queue.add (1); queue.add (5); queue.add (2); queue.add (3); queue.add (4); queue.drainTo (polledElements); assertThat (polledElements). obsahuje Presne (1, 2, 3, 4, 5);

Ako vidíme, napriek pridaniu prvkov do frontu v náhodnom poradí budú zoradené, keď ich začneme vyzývať. Je to preto, lebo Celé číslo triedne náradie Porovnateľný ktoré sa následne použijú na to, aby sme sa ubezpečili, že ich z frontu vyberieme vzostupne.

To tiež stojí za zmienku keď sa dva prvky porovnávajú a sú rovnaké, neexistuje záruka, ako budú zoradené.

3. Pomocou Fronta blokovať

Keby sme mali do činenia so štandardnou radou, zavolali by sme anketa () načítať prvky. Ak bol však rad prázdny, zavolajte na anketa () by sa vrátil nulový.

The Priorita blokovania realizuje BlockingQueue rozhranie, ktoré nám poskytuje niekoľko ďalších metód, ktoré nám to umožňujú blokovať pri odstraňovaní z prázdneho frontu. Skúsme použiť vziať () metóda, ktorá by mala robiť presne toto:

Fronta PriorityBlockingQueue = nová PriorityBlockingQueue (); new Thread (() -> {System.out.println ("Polling ..."); try {Integer poll = queue.take (); System.out.println ("Polled:" + poll);} catch ( InterruptedException e) {e.printStackTrace ();}}). Start (); Thread.sleep (TimeUnit.SECONDS.toMillis (5)); System.out.println ("Pridávanie do frontu"); queue.add (1);

Aj keď pomocou spánok () je mierne krehký spôsob demonštrácie vecí, keď spustíme tento kód, uvidíme:

Anketa ... Pridanie do frontu Anketa: 1 

To dokazuje vziať () blokované, kým nebola pridaná položka:

  1. Vlákno vytlačí „Polling“, aby dokázalo, že je spustené
  2. Test sa potom na približne päť sekúnd pozastaví, aby sa preukázalo, že vlákno muselo volať vziať () týmto bodom
  3. Pridávame do poradia a mali by sme viac-menej okamžite vidieť „Polled: 1“, aby sme to dokázali vziať () vrátil prvok hneď, ako bude k dispozícii

Za zmienku tiež stojí, že BlockingQueue rozhranie nám tiež poskytuje spôsoby blokovania pri pridávaní do plných radov.

Avšak a Priorita blokovania je neobmedzený. To znamená, že nikdy nebude plná, takže bude vždy možné pridávať nové prvky.

4. Spoločné používanie blokovania a určovania priorít

Teraz, keď sme vysvetlili dva kľúčové pojmy a Fronta prioritného blokovania, využime ich obidve spolu. Môžeme jednoducho rozšíriť náš predchádzajúci príklad, ale tentokrát do fronty pridáme ďalšie prvky:

Thread thread = new Thread (() -> {System.out.println ("Polling ..."); while (true) {try {Integer poll = queue.take (); System.out.println ("Polled: "+ hlasovanie);} catch (InterruptedException e) {e.printStackTrace ();}}}); thread.start (); Thread.sleep (TimeUnit.SECONDS.toMillis (5)); System.out.println ("Pridávanie do frontu"); queue.addAll (newArrayList (1, 5, 6, 1, 2, 6, 7)); Thread.sleep (TimeUnit.SECONDS.toMillis (1));

Aj keď je to opäť trochu krehké kvôli použitiu spánok (), stále nám ukazuje platný prípad použitia. Teraz máme rad, ktorý sa blokuje a čaká na pridanie prvkov. Potom pridávame veľa prvkov naraz a potom ukazujeme, že sa s nimi bude narábať v prioritnom poradí. Výstup bude vyzerať takto:

Anketa ... Pridanie do frontu Anketa: 1 Anketa: 1 Anketa: 2 Anketa: 5 Anketa: 6 Anketa: 6 Anketa: 7

5. Záver

V tejto príručke sme si ukázali, ako môžeme používať a Priorita blokovania aby sme vlákno zablokovali, kým do neho nepridajú nejaké položky, a tiež aby sme tieto položky dokázali spracovať na základe ich priority.

Implementáciu týchto príkladov možno nájsť na GitHub. Toto je projekt založený na Maven, takže by mal byť ľahko spustiteľný tak, ako je.


$config[zx-auto] not found$config[zx-overlay] not found