Как объяснить операцию обработки семафора? - PullRequest
0 голосов
/ 30 сентября 2010

Далее - простая реализация семафора.

public class Semaphore {
  private boolean signal = false;

  public synchronized void take() {
   this.signal = true;
   this.notify();
  }

  public synchronized void release() throws InterruptedException {
   while (!this.signal) wait();
   this.signal = false;
  }
 }

Правда ли, что при вызове take () семафор имитирует получение сигнала и пробуждает случайно выбранный поток (если он действительно существует), а также при вызове release (), если сигнал не был получен, семафор заставляет текущий (запускающий) поток ждать уведомления (), но устанавливает для получения сигнала значение false?

И означает ли это, что если у меня будет один семафор для 3 потоков, мне придется запустить пару take () - release () для каждого потока в части кода, что не является потокобезопасным?

1 Ответ

0 голосов
/ 30 сентября 2010

Да, как написано, take() будет пробуждать случайно выбранный поток из заблокированных в release(), а release() будет ожидать вызова take(), если signal ложно при входе. Это говорит о том, что у вас есть имена take() и release() в обратном направлении: take() должен быть блокирующим вызовом.

Это двоичный семафор, так как он имеет только два состояния. Если вы используете его как мьютекс, вам понадобится пара take() - release(), заключающая в себе код, который необходимо изолировать. Однако в этом случае вам лучше использовать простой мьютекс.

Семафоры имеют много применений (см. «Маленькая книга семафоров»), но, как правило, их сложнее правильно использовать, чем мьютексы и мониторы / переменные условий.

...