Java BlockingQueue
Java BlockingQueue akzeptiert keine Nullwerte und wirft eine NullPointerException, wenn Sie versuchen, einen Nullwert in die Warteschlange zu speichern. Java BlockingQueue-Implementierungen sind threadsicher. Alle Warteschlangenmethoden sind von Natur aus atomar und verwenden interne Sperren oder andere Formen der Nebenläufigkeitssteuerung. 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 Sorgen machen, auf verfügbaren Platz für den Produzenten oder verfügbare Objekte für den Konsumenten 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 der BlockingQueue werden wir die ArrayBlockingQueue-Implementierung verwenden. Folgend sind einige wichtige Methoden, die Sie kennen sollten.
Wichtige Methoden
- put(E e): Diese Methode wird verwendet, um Elemente in die Warteschlange einzufügen. Wenn die Warteschlange voll ist, wartet sie, bis Platz verfügbar ist.
- E take(): Diese Methode holt und entfernt das Element vom Kopf der Warteschlange. Wenn die Warteschlange leer ist, wartet sie, bis ein Element verfügbar ist.
Java BlockingQueue Beispiele
Message
package com.journaldev.concurrency;
public class Message {
private String msg;
public Message(String str){
this.msg=str;
}
public String getMsg() {
return msg;
}
}
Producer
package com.journaldev.concurrency;
import java.util.concurrent.BlockingQueue;
public class Producer implements Runnable {
private BlockingQueue<Message> queue;
public Producer(BlockingQueue<Message> q){
this.queue=q;
}
@Override
public void run() {
//produce messages
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();
}
}
//adding exit message
Message msg = new Message("exit");
try {
queue.put(msg);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Consumer
package com.journaldev.concurrency;
import java.util.concurrent.BlockingQueue;
public class Consumer implements Runnable{
private BlockingQueue<Message> queue;
public Consumer(BlockingQueue<Message> q){
this.queue=q;
}
@Override
public void run() {
try{
Message msg;
//consuming messages until exit message is received
while((msg = queue.take()).getMsg() !="exit"){
Thread.sleep(10);
System.out.println("Consumed "+msg.getMsg());
}
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
Service
package com.journaldev.concurrency;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class ProducerConsumerService {
public static void main(String[] args) {
//Creating BlockingQueue of size 10
BlockingQueue<Message> queue = new ArrayBlockingQueue<>(10);
Producer producer = new Producer(queue);
Consumer consumer = new Consumer(queue);
//starting producer to produce messages in queue
new Thread(producer).start();
//starting consumer to consume messages from queue
new Thread(consumer).start();
System.out.println("Producer and Consumer has been started");
}
}
Ausgabe
Die Ausgabe des oben genannten 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 bei Produzenten und Konsumenten verwendet, um Nachrichten mit einiger Verzögerung zu produzieren und zu konsumieren.