דוגמת Java BlockingQueue

היום נתמקד ב-Java BlockingQueue. java.util.concurrent.BlockingQueue הוא תור Java שתומך בפעולות שממתינות שהתור יהיה לא ריק כאשר משיגים ומסירים אלמנט, וממתינות שתחזור חלל זמין בתור כאשר מוסיפים אלמנט.

Java BlockingQueue

Java BlockingQueue לא מקבל ערכים null וזורק NullPointerException אם נשאת לאחסן ערך null בתור. יישומים של Java BlockingQueue הם thread-safe. כל שיטות ההמתנה הן אטומיות בטבעם ומשתמשות בנעילות פנימיות או צורות אחרות של שליטה בקונקרנסי. ממשק Java BlockingQueue הוא חלק מהגדרות אוסף של Java והוא בעיקר משמש למימוש בעיה שלייצור-צרכן. אנו לא צריכים לדאוג להמתנה של חלל הזמינות לייצרן או לאובייקט הזמין לצרכן ב-BlockingQueue מאחר שזה מטופל על ידי מחלקות המימוש של BlockingQueue. Java מספקת מספר מימושים של BlockingQueue כגון ArrayBlockingQueue, LinkedBlockingQueue, PriorityBlockingQueue, SynchronousQueue וכו '. בעת מימוש בעיה שלייצור-צרכן ב-BlockingQueue, נשתמש במימוש של ArrayBlockingQueue. הנה כמה שיטות חשובות שעליכם לדעת.

  • put(E e): שיטה זו משמשת להכנסת אלמנטים לתור. אם התור מלא, היא ממתינה עד שייצרף מקום זמין.
  • 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.

בואו נממש את בעיה של יצרן-צרכן באמצעות BlockingQueue של ג'אווה כעת.

דוגמת BlockingQueue בג'אווה – הודעה

פשוט אובייקט ג'אווה רגיל שיעשה יצור על ידי היוצר ויתווסף לתור. תוכל גם לקרוא לזה כפועל או הודעת תור.

package com.journaldev.concurrency;

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

    public String getMsg() {
        return msg;
    }

}

דוגמת BlockingQueue בג'אווה – היוצר

כיתה היוצרת המייצרת הודעות ומכניסה אותם לתור.

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() {
        //ייצור הודעות
        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();
            }
        }
        //הוספת הודעת יציאה
        Message msg = new Message("exit");
        try {
            queue.put(msg);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

דוגמת BlockingQueue בג'אווה – צרכן

כיתה הצרכנית המעבדת את הודעות מהתור ומסיימת כאשר מקבלת הודעת יציאה.

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;
            //צריכת הודעות עד שמתקבלת הודעת יציאה
            while((msg = queue.take()).getMsg() !="exit"){
            Thread.sleep(10);
            System.out.println("Consumed "+msg.getMsg());
            }
        }catch(InterruptedException e) {
            e.printStackTrace();
        }
    }
}

דוגמה ל- Java BlockingQueue – שירות

סופית אנו צריכים ליצור שירות של BlockingQueue עבור היוצר והצרכן. שירות זה של היוצר והצרכן ייצור את ה-BlockingQueue בגודל קבוע ויחלק אותו עם היוצרים והצרכנים. שירות זה יפעיל את תהליכי היוצר והצרכן ויצא.

package com.journaldev.concurrency;

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

public class ProducerConsumerService {

    public static void main(String[] args) {
        //יצירת BlockingQueue בגודל 10
        BlockingQueue queue = new ArrayBlockingQueue<>(10);
        Producer producer = new Producer(queue);
        Consumer consumer = new Consumer(queue);
        //התחלת היוצר לייצר הודעות בתור
        new Thread(producer).start();
        //התחלת הצרכן לצרכן הודעות מהתור
        new Thread(consumer).start();
        System.out.println("Producer and Consumer has been started");
    }

}

הפלט של דוגמת ה- Java BlockingQueue המופיעה למעלה מוצג למטה.

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 משמש ביוצר ובצרכן כדי לייצר ולצרוך הודעות עם עיכוב מסוים.

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