【发布时间】:2014-05-06 02:46:03
【问题描述】:
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
Producer producer = new Producer("Producer ");
Consumer[] consumers = new Consumer[1];
for (int i = 0; i < consumers.length; i++) {
consumers[i] = new Consumer(producer,"Consumer " + i);
}
producer.start();
for (int i = 0; i < consumers.length; i++) {
consumers[i].start();
}
}
}
class Producer extends Thread{
public ArrayList<Integer> buffer;
public int bufferSize = 20;
int fillCount = 0;
int emptyCount = bufferSize;
Integer item;
public Producer(String name) {
super(name);
buffer = new ArrayList<>(bufferSize);
}
public void run() {
while(true) {
System.out.println("Producing");
item = new Integer(1000);
downEmpty();
addItemtoBuffer();
increaseFill();
}
}
private void addItemtoBuffer() {
synchronized (buffer) {
buffer.add(item);
System.out.println("Produced " + getName() + fillCount + " " + emptyCount);
}
}
private void downEmpty() {
while(emptyCount <= 0) {
//Busy Waiting when buffer is full
//System.out.println("EmptyCount " + emptyCount);
}
--emptyCount;
}
private void increaseFill() {
++fillCount;
}
}
class Consumer extends Thread{
private Producer producer;
private ArrayList<Integer> buffer;
public Consumer(Producer producer, String name) {
super(name);
this.producer = producer;
buffer = producer.buffer;
}
public void run() {
while(true) {
downFill();
consume();
increaseEmpty();
}
}
private void downFill() {
while(producer.fillCount <= 0) {
//Busy Waiting when buffer is empty
//System.out.println("fillCount" + producer.fillCount + " EmptyCount" + producer.emptyCount);
}
--producer.fillCount;
}
private void increaseEmpty() {
++producer.emptyCount;
}
private void consume() {
synchronized (buffer) {
buffer.remove(buffer.size()-1);
System.out.println("Consumed");
}
}
}
这是我对生产者消费者问题的解决方案。目前它只有 1 个生产者和 1 个消费者。我的问题是当我运行它时,Producer 会产生直到缓冲区已满并进入忙碌等待状态。消费者消费了一段时间,但停止让生产者完全填满缓冲区。此时 fillCount 为 20。
我不知道为什么消费者不会消费。如果 fillCount 小于或等于 0,它唯一的忙等待。另一种可能性是它正在等待同步块,但由于生产者正忙于等待,缓冲区必须是空闲的。
但还有一件更大的事情。如果我在忙碌的等待中取消注释系统输出,它就可以工作!虽然有点奇怪。
我需要帮助,我需要让它与任意数量的生产者和消费者合作。我的问题是为什么消费者不消费并且可能让它与多个消费者一起使用。
【问题讨论】:
-
您如何确保对
emptyCount和fillCount的访问是线程安全的?一个线程中的更改是否对另一个线程可见?您是否尝试过使用 AtomicInteger 代替? -
我最初有 emptyCount 和 fillCount 是 Integer 对象并同步它们,但我又回去了。将尝试 AtomicIntegers
-
记住只同步
final对对象的引用。在变化的参考上同步并没有你认为的那样;)
标签: java multithreading