制片人 - 消费者:并行编程

时间:2018-05-16 10:39:21

标签: multithreading parallel-processing producer-consumer

我的问题很简单:这个程序是否可以模拟生产者 - 消费者问题?

public class ProducerConsumer {

    public static void main(String[] args) {

         Consumers c = new Consumers(false, null);
         Producer p = new Producer(true, c);
         c.p = p;

         p.start();
         c.start();
    }

}

class Consumers extends Thread {
    boolean hungry; // I want to eat
    Producer p;

    public Consumers(boolean hungry, Producer p) {
        this.hungry = hungry;
        this.p = p;

    }

    public void run() {
        while (true) {
            // While the producer want to produce, don't go
            while (p.nice == true) {
              // Simulation of the waiting, to check if it doesn't wait and 
              //`eat at the same time or any bad interleavings
              System.out.println("Consumer doesn't eat");
              try {
                sleep(500);
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
          }

        for (int i = 0; i < 3; i++) {
            try {
                sleep(1000);
                // Because the consumer eat, the producer is boring and
                // want to produce, that's the meaning of the nice.
                // This line makes the producer automatically wait in the
                // while loop as soon as it has finished to produce.
                p.nice = true;

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Consumer eat");
        }
        hungry = false;
        System.out.println("\nConsumer doesn't eat anymore\n");
    }
     }
}

class Producer extends Thread {
    boolean nice;
    Consumers c;

    public Producer(boolean nice, Consumers c) {
        this.nice = nice;
        this.c = c;
    }

    public void run() {
        while (true) {
            /**
             * I begin with the producer so the producer, doesn't enter the 
             * loop because no food has been produce and hungry is
             * exceptionally false because that's how work this program,
             * so at first time the producer doesn't enter the loop.
             */
             while (c.hungry == true) {
                try {
                    sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Producer doesn't produce");
             }

            /**
             * While the consumer wait in the while loop of its run method 
             * which means that nice is true the producer produce and during
             * the production the consumer become hungry, which make the 
             * loop "enterable" for theproducer. The advantage of this is
             * that the producer already knows that it has to go away after 
             * producing, the consumer doesn't need to tell him
             * Produce become true, and it has no effect for the first round
             */
             for (int i = 0; i < 3; i++) {
                 try {
                     sleep(1000);
                     c.hungry = true;

                 } catch (InterruptedException e) {
                     e.printStackTrace();
                 }
                 System.out.println("Producer produce");
             }

             /**
             * After a while, producer produce, the consumer is still in the 
             * loop, so we can tell him he can go, but we have to make
             * sure that the producer doesn't pass the loop before the 
             * consumer goes out and set back produce to true will lead the
             * consumer to be stuck again, and that's the role of the, 
             * c.hungry in the for loop, because the producer knows it has
             * some client, it directly enter the loop and so can't
             * starve the client.
             */
             System.out.println("\nProducer doesn't produce anymore\n");
             nice = false;
        }
    }
}

我没有使用任何同步,等待或通知,所以对于并行编程问题,它似乎很奇怪,但是当我运行它时没有任何死锁,饥饿或错误的交错,生产者产生,然后停止,消费者吃了然后又停止了我想要的时间。

我在某个地方作弊吗?

谢谢!

P.S-我不知道为什么但是问题的第一行没有出现,只是说你好了

1 个答案:

答案 0 :(得分:0)

首先,小心命名,“消费者”是误导,你只是模拟一个孤独的消费者。尼斯也可以用“生产”代替。

其次,你正在使用while(条件)sleep,这基本上是一个效率较低,不受保护的信号量等待版本,所以你确实使用了一种等待形式。

E.G。

while (p.nice == true) {
          System.out.println("Consumer doesn't eat");
          try {
            sleep(500);
          } catch (InterruptedException e) {
              e.printStackTrace();
          }
      }

是你的P()

System.out.println("\nProducer doesn't produce anymore\n");
nice = false;

是你的V()

然而,这种方法效率低下(等待线程要么忙着等待,要么能够一直睡觉)和不受保护(因为没有保护同时访问 nice 饥饿,您将无法与更多的消费者或制作人一起扩展此计划。

希望这有帮助。