我尝试根据官方的oracle示例(http://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html)创建一个消费者生产者。
这个解决方案给我带来了一个问题,因为不知何故消耗(或生产)被执行了两次。
示例输出:
0.27621192120612414
0.24838246527492802、0.30404137713732027
0.8848100139189661
0.9910138279470992、0.778606199890833
0.17368370874476935、0.5661899414440023 ......
我的代码与发布的预言机非常相似:
import java.util.Random;
public class Consumer implements Runnable {
private SharedData sharedData;
public Consumer(SharedData sharedData) {
this.sharedData = sharedData;
}
@
Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i < 10; i++) {
double result = this.sharedData.calc();
System.out.println(result);
try {
Thread.sleep(20);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class Producer implements Runnable {
private SharedData sharedData;
private Random numGenerator = new Random();
public Producer(SharedData sharedData) {
this.sharedData = sharedData;
}
@
Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i < 10; i++) {
double firstNum = numGenerator.nextDouble();
double secondNum = numGenerator.nextDouble();
this.sharedData.store(firstNum, secondNum);
System.out.println(firstNum + ", " + secondNum);
try {
Thread.sleep(20);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class SharedData {
private double x = 0;
private double y = 0;
private boolean empty = true;
public synchronized double calc() {
while (empty) {
try {
wait();
} catch (InterruptedException e) {}
}
empty = true;
notifyAll();
return (x + y) / 2;
}
public synchronized void store(double x, double y) {
while (!empty) {
try {
wait();
} catch (InterruptedException e) {}
}
// Toggle status.
empty = false;
this.x = x;
this.y = y;
notifyAll();
}
}
最佳答案
您的 System.out.println 调用不在任何同步部分中,因此即使生产者在消费者消费之前进行生产,也无法保证其输出将在消费者输出之前出现:
- 生产者线程生产,消费者线程等待
- 消费者线程消费
- 消费者线程打印结果
- 生产者线程打印结果
将 System.out.println
调用放入同步部分中,您应该会看到消费者和生产者输出之间的严格交替。
关于java - 消费者生产者在java中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23890294/