Печать перед вызовом wait () в семафоре - PullRequest
0 голосов
/ 06 ноября 2019

Я пытаюсь реализовать ограниченный буфер в Java, чтобы узнать больше о параллелизме. Несколько потоков получат доступ к этому буферу для использования методов add () и remove (). Я использую три семафора, чтобы это произошло (один для числа доступных элементов, количества доступных пространств и двоичного семафора для критической секции). Когда буфер заполнен / пуст, я бы хотел напечатать «буфер заполнен» или «буфер пуст» соответственно.

Я поместил инструкцию print для full / empty, прежде чем вызывать wait () в семафор. Это, однако, похоже, печатает полный / пустой гораздо больше, чем следует, и в неподходящее время. Я предполагаю, что это переключение контекста в неправильное время. Должен ли я изменить место, где я помещаю оператор печати?

Мой класс Semaphore, который может печатать полностью / пусто с параметром prtstmt

public class Semaphore {

  private String prtstmt;
  private int count;

  public semaphore(String prtstmt, int count) {
    this.count = count;
    this.prtstmt = prtstmt;
  }

  public synchronized void V(){
    count = count + 1;
    notify();
  }

  public synchronized void P(){
    count = count - 1;
    if (count < 0) {
      System.out.println(prtstmt);
      wait();
    }
  }

}

Ограниченный буфер

public class BoundedBufferUsingSemaphore {

private static final int SIZE = 10;

public static void main(String[] args) {

    Semaphore full = new Semaphore(0, "Buffer full!");
    Semaphore empty = new Semaphore(SIZE, "Buffer Empty!");
    Semaphore mutex = new Semaphore(1, null);
    Vector<Integer> sQueue = new Vector<Integer>();

    Thread producerThread = new Thread(new Runnable() {

        @Override
        public void run() {

            for (int i = 0; i < 5000; i++) {
                empty.p();
                mutex.p();
                System.out.println(Thread.currentThread().getName() + " is trying to insert item " + i);
                sQueue.add(i);
                mutex.v();
                full.v();
            }
        }
    });

    Thread consumerThread = new Thread(new Runnable() {

        @Override
        public void run() {
            while (true) {
                full.p();
                mutex.p();
                System.out.println(Thread.currentThread().getName() + " consuming item " + sQueue.remove(0));
                mutex.v();
                empty.v();
            }
        }
    });

    producerThread.setName("Producer");
    consumerThread.setName("Consumer");

    consumerThread.start();
    producerThread.start();

}
}

Пример вывода выглядит следующим образом

Consumer consuming item 5
Buffer empty!
Producer is trying to insert item 6
Producer is trying to insert item 7
Consumer consuming item 6
Producer is trying to insert item 7
Consumer consuming item 6
Buffer empty!
Consumer consuming item 5
Buffer empty!
Producer is trying to insert item 6
Producer is trying to insert item 7
Consumer consuming item 6
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...