0

我实现了生产者消费者问题,但我不明白为什么我的程序停止消费,即使生产者生产请帮助我找到错误并修复。

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) {
        }

    }
}
4

2 回答 2

4

如果将 while 循环放在同步方法中,消费者将永远不会释放锁。在里面放一些 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;
}
于 2013-09-06T14:05:58.313 回答
2

@greyfairer 的答案看起来是正确的,但为了后代,我建议您查看为ExecutorService您处理大部分代码的类,包括工作排队以及生产者和消费者之间的信号。您可能会将此作为练习,但如果没有,这里有一个很好的教程

标准中缺少的ExecutorService是限制未完成作业的数量,因此生产者不会通过排队太多作业来压倒内存。为此,您需要做一个有界队列并使用RejectedExecutionHandler.

有关更多详细信息,请参阅此答案:Process Large File for HTTP Calls in Java

于 2013-09-06T14:12:02.470 回答