Производитель-потребитель: параллельное программирование - PullRequest
0 голосов
/ 16 мая 2018

мой вопрос действительно прост: действительно ли эта программа является симуляцией проблемы производителя-потребителя?

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

Я не использовал синхронизацию, ожидание или уведомление, поэтому для проблемы параллельного программированияэто кажется очень странным, но когда я запускаю его, нет никаких тупиков, голодания или плохого чередования, производитель производит, затем останавливает, потребитель ест, а затем останавливается и снова столько раз, сколько я хотел.

Я где-нибудь обманывал?

Спасибо!

PS - Я не знаю почему, но первая строка моего вопроса не появляется, просто было сказано "привет"

1 Ответ

0 голосов
/ 16 мая 2018

Прежде всего, осторожно с именами, «Потребители» вводят в заблуждение, вы только симулируете одинокого потребителя.Nice также можно заменить на «production».

Во-вторых, вы используете while (condition) sleep, который в основном является менее эффективной, незащищенной версией семафорного ожидания, поэтому вы использовали формуподождите.

EG

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 и голодных , вы выиграли 'я не смогу расширить эту программу за счет большего числа потребителей или производителей).

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...