我正在從java documentation正在學習線程同步。我實施了一個着名的問題生產者 - 消費者問題。但它沒有按預期給出結果。我在HERE,HERE,HERE,HERE,HERE和一些其他堆棧交換站點和非堆棧交換站點上搜索了很多關於這個問題,但無法解決我的問題。這裏是我的代碼:生產者消費者沒有給出想要的結果
GetSetItem.java
public class GetSetItem {
private volatile boolean available = false;
private int item;
public synchronized void set(int item) {
while(available) {
try {
wait();
} catch (InterruptedException ie) {
System.err.println("Interrupted: " + ie.getMessage());
}
}
this.item = item;
available = true;
notifyAll();
}
public synchronized int get() {
while(!available) {
try {
wait();
} catch (InterruptedException ie) {
System.err.println("Interrupted: " + ie.getMessage());
}
}
available = false;
notifyAll();
return item;
}
}
Consumer.java
public class Consumer implements Runnable {
private int number; // Just for show #1,#2 etc. For future use
private GetSetItem consumer;
public Consumer(GetSetItem item, int seq) {
consumer = item;
number = seq;
}
@Override
public void run() {
int value = -1;
for(int i = 0; i < 10; i++) {
value = consumer.get();
System.out.println("Consumer #" + number + " get: " + value);
}
}
}
Producer.java
public class Producer implements Runnable {
private GetSetItem producer;
private int number = 0;
public Producer(GetSetItem item, int seq) {
producer = item;
number = seq;
}
@Override
public void run() {
for(int i = 0; i < 10; i++) {
producer.set(i);
System.out.println("Producer #" + number + " Put: " + i);
}
}
}
ProducerConsumerMain.java
public class ProducerConsumerMain {
public static void main(String[] args) {
GetSetItem item = new GetSetItem();
Producer p = new Producer(item, 1);
Consumer c = new Consumer(item, 1);
new Thread(p).start();
new Thread(c).start();
}
}
輸出是:
Consumer #1 get: 0
Producer #1 Put: 0
Producer #1 Put: 1
Consumer #1 get: 1
Producer #1 Put: 2
Consumer #1 get: 2
Producer #1 Put: 3
Consumer #1 get: 3
Producer #1 Put: 4
Producer #1 Put: 5
Consumer #1 get: 4
Consumer #1 get: 5
Producer #1 Put: 6
Producer #1 Put: 7
Consumer #1 get: 6
Consumer #1 get: 7
Consumer #1 get: 8
Producer #1 Put: 8
Producer #1 Put: 9
Consumer #1 get: 9
但產量應該在生產 - >消費格式。這意味着消費者只有在生產商可以購買和生產的情況下才能消費該產品。我也試過private boolean available = false
而不是private volatile boolean available = false;
,但沒有收到預期的輸出。
那麼請告訴我我在做什麼錯,以及如何成功實現這個問題。
我可以用 「如果(可用)」 語句,而不是 「而(可用)」 沒有,因爲我研究了「等待改變的行爲( )「方法將阻止對象,直到」notify()或notifyAll()「被調用。 – 2015-02-24 11:36:04
阻止是你想要達到的目標:你的'消費者'必須等到'生產者'說完成,然後'生產者'不能產生任何新的東西,直到價值被消耗完。在這種情況下你可以使用'if',但是如果你有多個'Producer'和'Consumer's,那麼你會遇到麻煩。最好使用'notify()',因爲它只喚醒一個線程。那麼,使用'if'可能是安全的,但它並不重要。 – DennisW 2015-02-24 11:40:40