0

my question is really simple : is this program valid as a simulation of the producer-consumer problem ?

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;
        }
    }
}

I didn't use any synchronization, wait or notify, so for a parallel programming problem it seems very strange, but when I run it there aren't any deadlocks, starvation or bad interleavings, the producer produces, then stop, the consumer eats and then stops and again as many time as I wanted.

Have I cheat somewhere ?

Thanks !

P.S- I don't know why but the first line of my question doesn't appear, it was just said hello

Kent
  • 3
  • 4

1 Answers1

0

First of all, careful with the naming, "Consumers" is misleading, you are only simulating a lone consumer. Nice can also be replaced with "producing".

Secondly, you're using while(condition) sleep, which is basically the less efficient, non protected version of a semaphore wait, so you did use a form of wait.

E.G.

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

is your P()

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

is your V()

This method, however is both inefficient (the waiting thread is either busy waiting or sleeps for a moment while being able to go) and unprotected (because there is no protection for simultaneous access of nice and hungry, you won't be able to expand this program with more Consumers or Producers).

Hope this helps.

Ika
  • 21
  • 5