Я пытаюсь реализовать ограниченный буфер в 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