Veiledning til PriorityBlockingQueue i Java

1. Introduksjon

I denne artikkelen vil vi fokusere på PriorityBlockingQueue klasse og gå gjennom noen praktiske eksempler.

Starter med antagelsen om at vi allerede vet hva en er, vil vi først demonstrere hvordan elementer i PriorityBlockingQueue er ordnet etter prioritet.

Etter dette vil vi demonstrere hvordan denne typen kø kan brukes til å blokkere en tråd.

Til slutt vil vi vise hvordan bruk av disse to funksjonene sammen kan være nyttig når du behandler data på tvers av flere tråder.

2. Prioritet av elementer

I motsetning til en standard kø, kan du ikke bare legge til noen type element i en PriorityBlockingQueue. Det er to alternativer:

  1. Legge til elementer som implementeres Sammenlignelig
  2. Legge til elementer som ikke implementeres Sammenlignelig, under forutsetning av at du oppgir en Komparator også

Ved å bruke enten Komparator eller Sammenlignelig implementeringer for å sammenligne elementer, PriorityBlockingQueue vil alltid bli sortert.

Målet er å implementere sammenligningslogikk på en måte som elementet med høyest prioritet bestilles alltid først. Så når vi fjerner et element fra køen vår, vil det alltid være det som har høyest prioritet.

Til å begynne med, la oss bruke køen vår i en enkelt tråd, i motsetning til å bruke den over flere. Ved å gjøre dette gjør det det enkelt å bevise hvordan elementer bestilles i en enhetstest:

PriorityBlockingQueue kø = ny PriorityBlockingQueue (); ArrayList polledElements = ny ArrayList (); kø.tillegg (1); kø.tillegg (5); kø.tillegg (2); kø.tillegg (3); kø.tillegg (4); que.drainTo (polledElements); assertThat (polledElements) .containsAkkurat (1, 2, 3, 4, 5);

Som vi kan se, til tross for å legge elementene til køen i tilfeldig rekkefølge, vil de bli bestilt når vi begynner å avstemme dem. Dette er fordi Heltall klasse redskaper Sammenlignbar, som igjen vil bli brukt til å sikre at vi tar dem ut av køen i stigende rekkefølge.

Det er også verdt å merke seg det når to elementer blir sammenlignet og er like, er det ingen garanti for hvordan de vil bli bestilt.

3. Bruke å blokkere

Hvis vi hadde å gjøre med en standard kø, ville vi ringe avstemming() for å hente ut elementer. Imidlertid, hvis køen var tom, ring til avstemming() ville komme tilbake null.

De PriorityBlockingQueue implementerer BlockingQueue grensesnitt, som gir oss noen ekstra metoder som lar oss blokker når du fjerner fra en tom kø. La oss prøve å bruke ta() metode, som skal gjøre akkurat det:

PriorityBlockingQueue kø = ny PriorityBlockingQueue (); ny tråd (() -> {System.out.println ("Polling ..."); prøv {Integer poll = queue.take (); System.out.println ("Polled:" + poll);} catch ( InterruptedException e) {e.printStackTrace ();}}). Start (); Thread.sleep (TimeUnit.SECONDS.toMillis (5)); System.out.println ("Legger til i køen"); kø.tillegg (1);

Selv om du bruker søvn() er en litt sprø måte å demonstrere ting på, når vi kjører denne koden vil vi se:

Polling ... Legger til i køen: 1 

Dette beviser det ta() blokkert til et element ble lagt til:

  1. Tråden vil skrive ut “Polling” for å bevise at den er startet
  2. Testen stopper deretter i rundt fem sekunder for å bevise at tråden må ha ringt ta() etter dette punktet
  3. Vi legger til i køen, og bør mer eller mindre øyeblikkelig se "Polled: 1" for å bevise det ta() returnerte et element så snart det ble tilgjengelig

Det er også verdt å nevne at BlockingQueue grensesnittet gir oss også måter å blokkere når vi legger til i full kø.

Imidlertid, a PriorityBlockingQueue er ubegrenset. Dette betyr at det aldri vil bli fullt, og dermed vil det alltid være mulig å legge til nye elementer.

4. Bruke blokkering og prioritering sammen

Nå som vi har forklart de to nøkkelbegrepene til a PriorityBlockingQueue, la oss bruke dem begge sammen. Vi kan ganske enkelt utvide vårt forrige eksempel, men denne gangen legger du til flere elementer i køen:

Trådtråd = ny tråd (() -> {System.out.println ("Polling ..."); mens (true) {prøv {Integer poll = queue.take (); System.out.println ("Polled: "+ avstemning);} fangst (InterruptedException e) {e.printStackTrace ();}}}); thread.start (); Thread.sleep (TimeUnit.SECONDS.toMillis (5)); System.out.println ("Legger til i køen"); kø.addAll (newArrayList (1, 5, 6, 1, 2, 6, 7)); Thread.sleep (TimeUnit.SECONDS.toMillis (1));

Igjen, mens dette er litt sprø på grunn av bruken av søvn(), det viser oss fremdeles en gyldig brukssak. Vi har nå en kø som blokkerer, og venter på at elementer skal legges til. Vi legger deretter til mange elementer på en gang, og viser deretter at de vil bli håndtert i prioritert rekkefølge. Utgangen vil se slik ut:

Polling ... Legger til i kø Pollet: 1 Pollet: 1 Pollet: 2 Pollet: 5 Pollet: 6 Pollet: 6 Pollet: 7

5. Konklusjon

I denne guiden har vi demonstrert hvordan vi kan bruke en PriorityBlockingQueue for å blokkere en tråd til noen elementer er lagt til den, og også at vi er i stand til å behandle disse elementene basert på deres prioritet.

Implementeringen av disse eksemplene finner du på GitHub. Dette er et Maven-basert prosjekt, så det skal være enkelt å kjøre som det er.


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