Voorbeeld van Java BlockingQueue

Vandaag zullen we kijken naar Java BlockingQueue. java.util.concurrent.BlockingQueue is een Java Queue die operaties ondersteunt die wachten tot de wachtrij niet leeg is bij het ophalen en verwijderen van een element, en wachten tot er ruimte beschikbaar is in de wachtrij bij het toevoegen van een element.

Java BlockingQueue

Java BlockingQueue accepteert geen null-waarden en gooit een NullPointerException als je probeert een null-waarde op te slaan in de wachtrij. Java BlockingQueue-implementaties zijn thread-safe. Alle wachtrijmethoden zijn atomair van aard en gebruiken interne vergrendelingen of andere vormen van gelijktijdigheidsbeheer. De Java BlockingQueue-interface maakt deel uit van het Java Collections-framework en wordt voornamelijk gebruikt voor het implementeren van het producent-consumentprobleem. We hoeven ons geen zorgen te maken over het wachten op ruimte voor de producent of op het beschikbaar zijn van een object voor de consument in BlockingQueue, omdat dit wordt afgehandeld door implementatieklassen van BlockingQueue. Java biedt verschillende BlockingQueue-implementaties zoals ArrayBlockingQueue, LinkedBlockingQueue, PriorityBlockingQueue, SynchronousQueue, enz. Bij het implementeren van het producent-consumentprobleem in BlockingQueue zullen we de implementatie van ArrayBlockingQueue gebruiken. Hier zijn enkele belangrijke methoden die je moet kennen.

  • put(E e): Deze methode wordt gebruikt om elementen in de wachtrij in te voegen. Als de wachtrij vol is, wacht het tot er ruimte beschikbaar is.
  • E take(): This method retrieves and remove the element from the head of the queue. If queue is empty it waits for the element to be available.

Laten we nu het producent-consumerprobleem implementeren met behulp van Java BlockingQueue.

Java BlockingQueue Voorbeeld – Bericht

Gewoon een normaal Java-object dat door de producent wordt geproduceerd en aan de wachtrij wordt toegevoegd. Je kunt het ook payload of wachtrijbericht noemen.

package com.journaldev.concurrency;

public class Message {
    private String msg;
    
    public Message(String str){
        this.msg=str;
    }

    public String getMsg() {
        return msg;
    }

}

Java BlockingQueue Voorbeeld – Producent

Producentenklasse die berichten zal creëren en deze in de wachtrij zal plaatsen.

package com.journaldev.concurrency;

import java.util.concurrent.BlockingQueue;

public class Producer implements Runnable {

    private BlockingQueue queue;
    
    public Producer(BlockingQueue q){
        this.queue=q;
    }
    @Override
    public void run() {
        // berichten produceren
        for(int i=0; i<100; i++){
            Message msg = new Message(""+i);
            try {
                Thread.sleep(i);
                queue.put(msg);
                System.out.println("Produced "+msg.getMsg());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        // exitbericht toevoegen
        Message msg = new Message("exit");
        try {
            queue.put(msg);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

Java BlockingQueue Voorbeeld – Consument

Consumentenklasse die berichten uit de wachtrij zal verwerken en wordt beëindigd wanneer het exitbericht is ontvangen.

package com.journaldev.concurrency;

import java.util.concurrent.BlockingQueue;

public class Consumer implements Runnable{

private BlockingQueue queue;
    
    public Consumer(BlockingQueue q){
        this.queue=q;
    }

    @Override
    public void run() {
        try{
            Message msg;
            // berichten consumeren totdat het exitbericht is ontvangen
            while((msg = queue.take()).getMsg() !="exit"){
            Thread.sleep(10);
            System.out.println("Consumed "+msg.getMsg());
            }
        }catch(InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Voorbeeld van Java BlockingQueue – Service

Tenslotte moeten we een BlockingQueue-service maken voor producent en consument. Deze producent-consumentenservice zal de BlockingQueue maken met een vaste grootte en delen met zowel producenten als consumenten. Deze service zal producent- en consumentendraden starten en afsluiten.

package com.journaldev.concurrency;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class ProducerConsumerService {

    public static void main(String[] args) {
        // Het creëren van een BlockingQueue van grootte 10
        BlockingQueue queue = new ArrayBlockingQueue<>(10);
        Producer producer = new Producer(queue);
        Consumer consumer = new Consumer(queue);
        // Het starten van de producent om berichten in de wachtrij te produceren
        new Thread(producer).start();
        // Het starten van de consument om berichten uit de wachtrij te consumeren
        new Thread(consumer).start();
        System.out.println("Producer and Consumer has been started");
    }

}

De uitvoer van het bovenstaande Java BlockingQueue-voorbeeldprogramma wordt hieronder weergegeven.

Producer and Consumer has been started
Produced 0
Produced 1
Produced 2
Produced 3
Produced 4
Consumed 0
Produced 5
Consumed 1
Produced 6
Produced 7
Consumed 2
Produced 8
...

Java Thread sleep wordt gebruikt in producent en consument om berichten te produceren en consumeren met wat vertraging.

Source:
https://www.digitalocean.com/community/tutorials/java-blockingqueue-example