Heute werden wir uns mit der Java BlockingQueue befassen. java.util.concurrent.BlockingQueue
ist eine Java-Warteschlange, die Operationen unterstützt, die darauf warten, dass die Warteschlange nicht leer wird, wenn ein Element abgerufen und entfernt wird, und darauf warten, dass Platz in der Warteschlange verfügbar wird, wenn ein Element hinzugefügt wird.
Java BlockingQueue
Java BlockingQueue akzeptiert keine
null
-Werte und wirft eine NullPointerException
auf, wenn Sie versuchen, einen Nullwert in die Warteschlange zu speichern. Java BlockingQueue-Implementierungen sind thread-sicher. Alle Warteschlangenmethoden sind atomarer Natur und verwenden interne Sperren oder andere Formen der Nebenläufigkeitskontrolle. Das Java BlockingQueue-Interface ist Teil des Java Collections Frameworks und wird hauptsächlich zur Implementierung des Produzenten-Konsumenten-Problems verwendet. Wir müssen uns keine Gedanken darüber machen, auf den verfügbaren Platz für den Produzenten oder das verfügbare Objekt für den Verbraucher in der BlockingQueue zu warten, da dies von den Implementierungsklassen der BlockingQueue gehandhabt wird. Java bietet mehrere BlockingQueue-Implementierungen wie ArrayBlockingQueue
, LinkedBlockingQueue
, PriorityBlockingQueue
, SynchronousQueue
usw. Bei der Implementierung des Produzenten-Konsumenten-Problems in BlockingQueue werden wir die ArrayBlockingQueue-Implementierung verwenden. Hier sind einige wichtige Methoden, die Sie kennen sollten.
put(E e)
: Diese Methode wird verwendet, um Elemente in die Warteschlange einzufügen. Wenn die Warteschlange voll ist, wartet sie darauf, dass Platz verfügbar wird.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.
Implementieren wir jetzt das Producer-Consumer-Problem mit der Java BlockingQueue.
Java BlockingQueue Beispiel – Nachricht
Ein einfaches Java-Objekt, das vom Producer erzeugt und in die Warteschlange eingefügt wird. Sie können es auch als Nutzlast oder Warteschlangennachricht bezeichnen.
package com.journaldev.concurrency;
public class Message {
private String msg;
public Message(String str){
this.msg=str;
}
public String getMsg() {
return msg;
}
}
Java BlockingQueue Beispiel – Producer
Producer-Klasse, die Nachrichten erstellt und sie in die Warteschlange einfügt.
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() {
// Nachrichten erzeugen
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();
}
}
// Exit-Nachricht hinzufügen
Message msg = new Message("exit");
try {
queue.put(msg);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Java BlockingQueue Beispiel – Consumer
Consumer-Klasse, die Nachrichten aus der Warteschlange verarbeitet und beendet wird, wenn die Exit-Nachricht empfangen wird.
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;
// Nachrichten verbrauchen, bis die Exit-Nachricht empfangen wird
while((msg = queue.take()).getMsg() !="exit"){
Thread.sleep(10);
System.out.println("Consumed "+msg.getMsg());
}
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
Java BlockingQueue Beispiel – Dienst
Zum Schluss müssen wir einen BlockingQueue-Dienst für Produzenten und Konsumenten erstellen. Dieser Produzenten-Konsumenten-Dienst wird den BlockingQueue mit fester Größe erstellen und sowohl Produzenten als auch Konsumenten teilen. Dieser Dienst wird Produzenten- und Konsumenten-Threads starten und dann beenden.
package com.journaldev.concurrency;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class ProducerConsumerService {
public static void main(String[] args) {
// Erstellen eines BlockingQueue der Größe 10
BlockingQueue queue = new ArrayBlockingQueue<>(10);
Producer producer = new Producer(queue);
Consumer consumer = new Consumer(queue);
// Starten des Produzenten zum Erzeugen von Nachrichten in der Warteschlange
new Thread(producer).start();
// Starten des Konsumenten zum Konsumieren von Nachrichten aus der Warteschlange
new Thread(consumer).start();
System.out.println("Producer and Consumer has been started");
}
}
Die Ausgabe des obigen Java-BlockingQueue-Beispielprogramms wird unten angezeigt.
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 wird im Produzenten und Konsumenten verwendet, um Nachrichten mit einer Verzögerung zu erzeugen und zu konsumieren.
Source:
https://www.digitalocean.com/community/tutorials/java-blockingqueue-example