[英]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美分:
每次添加/刪除后,您將通知另一個線程。 你不應該那樣做。
您想要做的是:
制片人:
消費者:
您可能要使用條件 。
然后,您應該看看zapl的方法,他在評論中說道:使用代表100個批次的列表列表。
共享:有工作隊列(線程安全數據結構,我建議阻塞一個)。
制片人:
消費者:
請注意,如果您必須保留訂單,則只能使用一位消費者,也可以花費額外的精力來對結果進行排序。
感謝您的寶貴意見和建議。 我不明白為什么不鼓勵使用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.