[英]java producer consumer in batches
I am facing a problem in producer - consumer. 我在生产者-消费者中面临一个问题。 My requirement is:
我的要求是:
Producer produces 100 objects together and wait for consumer to consume. 生产者共同生产100个对象,并等待消费者消费。 Then Consumer consumes those 100 objects and wait for producer to produce.
然后,消费者消耗这100个对象并等待生产者生产。 And this process repeats.
并重复此过程。
The condition is that, producer should not produce until objects size is 0, and consumer should not consume until objects size is 100. ie . 条件是,生产者在对象大小为0之前不应该生产,而消费者在对象大小为100之前不应该消费。 producing and consuming in batches of size 100 only.
仅批量生产和消费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();
}
}
output : 输出:
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
Can anybody point out what I am exactly missing. 谁能指出我到底想念什么。 Thanks in advance
提前致谢
I am assuming an excercise, so this is my 2 cents: 我正在做运动,所以这是我的2美分:
You are notifying the other thread after each add/remove. 每次添加/删除后,您将通知另一个线程。 You should not do that.
你不应该那样做。
What you want to do is: 您想要做的是:
Producer: 制片人:
Consumer: 消费者:
You may want to use Conditions . 您可能要使用条件 。
Then you should take a look at zapl's approach, he gave in comment: Use a Queue of Lists which represent batches of 100 items. 然后,您应该看看zapl的方法,他在评论中说道:使用代表100个批次的列表列表。
Shared: Have work queue (threadsafe Datastructure, I suggest a blocking one). 共享:有工作队列(线程安全数据结构,我建议阻塞一个)。
Producer: 制片人:
Consumer(s): 消费者:
Mind that if you must keep the order you can either only use one consumer or take extra effort to enforce sorting of the result. 请注意,如果您必须保留订单,则只能使用一位消费者,也可以花费额外的精力来对结果进行排序。
Thnx for your valuable comments and suggestions. 感谢您的宝贵意见和建议。 I cannot understand why LinkedList usage is discouraged here.
我不明白为什么不鼓励使用LinkedList。 In my real time project, my productionCount will be more than millions, and this I have to process in batches of 10000. Below link was also helpful.
在我的实时项目中,我的productionCount将超过数百万,并且我必须按10000的批次进行处理。下面的链接也有帮助。 How to know if other threads have finished?
如何知道其他线程是否已完成?
Here is my implementation using only 2 threads. 这是我仅使用2个线程的实现。 One Producer & other main thread itself as Consumer
一个生产者和其他主线程本身作为消费者
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.