生产者消费者问题显示顺序错误

时间:2018-11-26 13:42:52

标签: java oop producer-consumer

下面的生产者消费者代码显示了错误的顺序(在生产者生产消费者消费之前。有时生产者生产许多物品(储藏室只允许一件))。为什么呢?

  public class CubbyHole {
    private int content;
    private boolean available=false;

   public synchronized int get() {
      while (available == false) {
         try {
            wait();
         } catch (InterruptedException e) {}
      }
      available = false;
      notify();
      return content;
   }
   public synchronized void put(int value) {
      while (available == true) {
         try {            
            wait();
         } catch (InterruptedException e) { } 
      }
      content = value;
      available = true;
      notifyAll();
      }
   } 

public class Consumer extends Thread {
    CubbyHole c;

    public Consumer(CubbyHole c){
        this.c=c;
    }

    public void run(){
        int val=0;
        for(int i =0;i<10;i++){
            val=c.get();
            System.out.println("consumer gets "+val);
        }
    }

}

public class Producer extends Thread {
    CubbyHole c;

    public Producer(CubbyHole c){
        this.c=c;
    }
    public void run(){
        for(int i=0;i<10;i++){
            c.put(i);
            System.out.println("Producer puts "+i);
        }

    }

}
public class Dimo {

    public static void main(String[] args) {
        CubbyHole c = new CubbyHole();
        Producer p = new Producer(c);
        Consumer con = new Consumer(c);
        p.start();
        con.start();

    }
}

此代码获得以下输出

Producer puts 0
Producer puts 1
consumer gets 0
consumer gets 1
Producer puts 2
Producer puts 3
consumer gets 2
consumer gets 3
Producer puts 4
consumer gets 4
consumer gets 5
Producer puts 5
Producer puts 6
consumer gets 6
Producer puts 7
Producer puts 8
consumer gets 7
consumer gets 8
Producer puts 9
consumer gets 9

任何人都可以解释这段代码有什么问题吗?如何在此代码中获得正确的订单?

1 个答案:

答案 0 :(得分:0)

检查这两行:

val=c.get();
System.out.println("consumer gets "+val);

可能发生的事情是,消费者呼叫了小孔并在其空闲时在那里等待。然后,它获取值并释放它。现在在这两行之间-在c.get()之后,在printlin之前,另一个线程可以完成其整个过程-调用put(i)并进行打印。届时,您将获得两个producer.put()值。

您应将打印零件移至立体孔代码中,以确保其打印所需的内容。