我实现了生产者消费者问题,但我不知道为什么我的程序停止消费,即使生产者生产请帮助我找到bug并修复。
import java.util.*;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class producerConsumer {
private Queue<Integer> queue = new LinkedList<Integer>();
private Random random = new Random();
private synchronized void addData(int data) {
while(queue.size()>=10) ;
queue.add(data);
}
private synchronized int takeData() {
while(queue.size()<=0) ;
return queue.poll();
}
private void producer() {
int data;
while(true) {
data=random.nextInt(100);
addData(data);
System.out.println("the producer produced :"+data);
}
}
private void consumer() {
try {
while(true) {
if(random.nextInt(10)==0) {
Thread.sleep(1000);
System.out.println("The consumed value:"+takeData()+";queue size is "+queue.size());
}
}
}catch(InterruptedException e) {
}
}
public static void main(String args[]) {
producerConsumer pc = new producerConsumer();
pc.process();
}
public void process() {
Thread t1 = new Thread(new Runnable(){
public void run() {
producer();
}
});
Thread t2 = new Thread(new Runnable(){
public void run() {
consumer();
}
});
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch(InterruptedException e) {
}
}
}
答案 0 :(得分:4)
如果将while循环放在synchronized方法中,则使用者永远不会释放锁。在里面放一些wait()/ notify()逻辑。或者使用一些标准的同步队列实现。
以下情况应该更好:
private synchronized void addData(int data) {
while(queue.size()>=10) wait(); //wait() will temporarily release lock
queue.add(data);
notifyAll();
}
private synchronized int takeData() {
while(queue.size()<=0) wait(); //wait() will temporarily release lock
int poll = queue.poll();
notifyAll();
return poll;
}
答案 1 :(得分:2)
@ greyfairer的答案看起来是正确的但是对于后代我建议你看看ExecutorService
类,它们会为你处理大部分代码,包括作业排队和生产者之间的信号传递和消费者。您可能会将此作为练习,但如果没有,则为good tutorial。
标准ExecutorService
缺少的是限制未完成的工作数量,因此生产者不会通过排队太多工作来压倒内存。为此,您需要执行有界队列并使用RejectedExecutionHandler
。
有关详细信息,请参阅此答案:Process Large File for HTTP Calls in Java