簡體   English   中英

批量Java生產者使用者

[英]java producer consumer in batches

我在生產者-消費者中面臨一個問題 我的要求是:

生產者共同生產100個對象,並等待消費者消費。 然后,消費者消耗這100個對象並等待生產者生產。 並重復此過程。

條件是,生產者在對象大小為0之前不應該生產,而消費者在對象大小為100之前不應該消費。 僅批量生產和消費100。

class Producer extends Thread {
private Queue<Integer> queue;
private int maxSize;

public Producer(Queue<Integer> queue, int maxSize, String name) {
    super(name);
    this.queue = queue;
    this.maxSize = maxSize;
}

@Override
public void run() {
    while (true) {
        synchronized (queue) {
            while (queue.size() == maxSize) {
                try {
                    System.out.println("Queue is full, "
                            + "Producer thread waiting for "
                            + "consumer to take something from queue");
                    queue.wait();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            Random random = new Random();
            int i = random.nextInt();
            System.out.println("Producing value : " + i);
            queue.add(i);
            queue.notifyAll();
        }
    }
}

}

class Consumer extends Thread {
private Queue<Integer> queue;
private int maxSize;

public Consumer(Queue<Integer> queue, int maxSize, String name) {
    super(name);
    this.queue = queue;
    this.maxSize = maxSize;
}

@Override
public void run() {
    while (true) {
        synchronized (queue) {
            while (queue.isEmpty()) {
                System.out.println("Queue is empty,"
                        + "Consumer thread is waiting"
                        + " for producer thread to put something in queue");
                try {
                    queue.wait();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            System.out.println("Consuming value : " + queue.remove());
            queue.notifyAll();
        }
    }
}

}

public class ProdConsReference {
public static void main(String args[]) { 
    Queue<Integer> buffer = new LinkedList<Integer>(); 
    int maxSize = 10; 
    Thread producer = new Producer(buffer, maxSize, "PRODUCER"); 
    Thread consumer = new Consumer(buffer, maxSize, "CONSUMER"); 
    producer.start(); 
    consumer.start(); 
    }
}

輸出:

      Queue is empty,Consumer thread is waiting for producer thread to put                             something in queue
      Producing value : 52648529
      Consuming value : 52648529
      Queue is empty,Consumer thread is waiting for producer thread to put something in queue
      Producing value : -2128028718
      Consuming value : -2128028718

誰能指出我到底想念什么。 提前致謝

我正在做運動,所以這是我的2美分:

每次添加/刪除后,您將通知另一個線程。 你不應該那樣做。

您想要做的是:

制片人:

  1. 檢查隊列是否為空。
  2. 如果是:生產100件商品(不是1!),然后通知消費者,跳到4。
  3. 如果沒有,請等待通知
  4. 循環到1.(不是2.!)

消費者:

  1. 檢查隊列是否已滿。
  2. 如果是:消費直到Queue為空 ,然后通知生產者。 跳到4。
  3. 如果沒有,請等待通知
  4. 循環到1.(不是2.!)

您可能要使用條件

如果這不是練習/作業

然后,您應該看看zapl的方法,他在評論中說道:使用代表100個批次的列表列表。

共享:有工作隊列(線程安全數據結構,我建議阻塞一個)。

制片人:

  • 取Batchsize和“任務”或要處理項目的總數。 我假設總數是整除的批大小。 否則在制作時必須考慮到這一點。
  • 將<batchsize>個項目產生到一個列表中(= batch)
  • 將批處理(項目列表)放入workQueue
  • 重復前兩個步驟,直到達到總數。

消費者:

  • 從工作隊列中進行批量處理(如果有/盡快)
  • 批量處理所有項目

請注意,如果您必須保留訂單,則只能使用一位消費者,也可以花費額外的精力來對結果進行排序。

感謝您的寶貴意見和建議。 我不明白為什么不鼓勵使用LinkedList。 在我的實時項目中,我的productionCount將超過數百萬,並且我必須按10000的批次進行處理。下面的鏈接也有幫助。 如何知道其他線程是否已完成?

這是我僅使用2個線程的實現。 一個生產者和其他主線程本身作為消費者

            package threading;

            import java.util.LinkedList;
            import java.util.Queue;
            import java.util.Set;
            import java.util.concurrent.CopyOnWriteArraySet;


            public class ProdConsumerApp implements ThreadCompleteListener{
                boolean isProductionOver;
                public static void main(String args[]) {
                    ProdConsumerApp prodConsumerApp = new ProdConsumerApp();
                    prodConsumerApp.procudeAndConsume();
                }

                private void procudeAndConsume(){
                    Queue<Integer> buffer = new LinkedList<Integer>(); 
                    int maxSize = 100; 
                    int productionCount = 1000;

                    Producer producer = new Producer(buffer, maxSize, "PRODUCER", productionCount); 
                    producer.addListener(this);
                    producer.start(); 
                    consume(buffer);

                    System.out.println("Bye");
                }

                public void consume(Queue<Integer> queue){
                    while(!isProductionOver){//check whether production completed?
                        synchronized (queue) {
                            //when queue size is 0, notify and wait.
                            while(queue.isEmpty()){
                                try {
                                    queue.notify();
                                    queue.wait();
                                } catch (Exception ex) {
                                    ex.printStackTrace();
                                }
                            }
                            //consume until queue is empty.
                            while(!queue.isEmpty()){
                                System.out.println("Consuming value : " + queue.remove());
                            }
                        }
                    }
                }

                @Override
                public void notifyOfThreadComplete(Thread thread) {
                    System.out.println("notified");
                    isProductionOver = true;
                }

            }

            class Producer extends Thread {
                private Queue<Integer> queue;
                private int maxSize;
                private int productionCount;

                public Producer(Queue<Integer> queue, int maxSize, String name, int productionCount) {
                    super(name);
                    this.queue = queue;
                    this.maxSize = maxSize;
                    this.productionCount = productionCount;
                }

                private final Set<ThreadCompleteListener> listeners = new CopyOnWriteArraySet<ThreadCompleteListener>();

                public final void addListener(final ThreadCompleteListener listener) {
                    listeners.add(listener);
                }
                public final void removeListener(final ThreadCompleteListener listener) {
                    listeners.remove(listener);
                }
                private final void notifyListeners() {
                    for (ThreadCompleteListener listener : listeners) {
                        listener.notifyOfThreadComplete(this);
                    }
                }

                @Override
                public void run() {
                    synchronized (queue) {
                        for(int i=1;i<=productionCount;i++){
                            System.out.println("Producing value : " + i);
                            queue.add(i);

                            //when queue size is maxSize, notify and wait.
                            while(queue.size() == maxSize){
                                try {
                                    queue.notify();
                                    if(i==productionCount){
                                        //if last item is produced, notify listeners that production is completed.
                                        notifyListeners();
                                        //exit from while() and later for() and thereby terminating Producer.
                                        break;
                                    }
                                    queue.wait();
                                } catch (Exception ex) {
                                    ex.printStackTrace();
                                }
                            }
                        }           
                    }
                }

            }


            interface ThreadCompleteListener {
                void notifyOfThreadComplete(final Thread thread);
            }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM