java - 消费者生产者在java中不起作用

标签 java synchronization

我尝试根据官方的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 调用不在任何同步部分中,因此即使生产者在消费者消费之前进行生产,也无法保证其输出将在消费者输出之前出现:

  1. 生产者线程生产,消费者线程等待
  2. 消费者线程消费
  3. 消费者线程打印结果
  4. 生产者线程打印结果

System.out.println 调用放入同步部分中,您应该会看到消费者和生产者输出之间的严格交替。

关于java - 消费者生产者在java中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23890294/

相关文章:

java - 如何在 Nashorn 中调用带有参数的匿名函数?

mysql - 如何同步两个不同方案的MySQL数据库?

java - 如何获取类级锁

c++ - 是否可以在 C、C++ 中使用类似 Java 的同步语句?

java - Java中 float 组的数据对齐算法

java - Amazon Hadoop 2.4 + Avro 1.77 : Found interface org. apache.hadoop.mapreduce.TaskAttemptContext,但预期类

Java:使用变量引用类变量

java - 如何从java中的字符串创建键/值映射(更复杂)

java - 嵌套同步块(synchronized block)的缺点