Java Semaphor не соблюдает аргумент? - PullRequest
0 голосов
/ 05 декабря 2018

Когда я использую семафору с 1 аргументом.А затем отпустите его дважды, это увеличит количество доступных разрешений до 2, но в идеале я уже упоминал, что хочу 1 блокировку.Теперь, когда у меня есть 2 доступных разрешения, два потока могут получить блокировку, которая отвергает цель аргумента.

Semaphor lock = new Semaphor(1);
lock.release();
lock.release();

lock.acquire(); // thread1
lock.acquire(); //thread2

Почему это так?

Ответы [ 3 ]

0 голосов
/ 05 декабря 2018
release()

Из Oracle doc: освобождает разрешение, увеличивая количество доступных разрешений на единицу.Если какие-либо потоки пытаются получить разрешение, то выбирается один и ему дается только что выпущенное разрешение.Этот поток (повторно) включен для целей планирования потоков.

Нет требования, чтобы поток, который выпускает разрешение, получил это разрешение путем вызова acqu ().Правильное использование семафора устанавливается соглашением о программировании в приложении.

0 голосов
/ 05 декабря 2018

Теперь, поскольку у меня есть 2 доступных разрешения, два потока могут получить блокировку, которая отвергает цель аргумента.

Он не побеждает цель Semaphore.Цель Semaphore состоит в том, чтобы реализовать счетную семафорную абстракцию, как описано здесь .

Почему Semaphore не учитывает предоставленный аргумент?

Это действительно чтит это.Но аргумент не ограничивает количество разрешений.Скорее он представляет количество разрешений, которые первоначально могут быть получены без блокировки.

Почему он так себя ведет?

Потому что (по мнению разработчиков Java) именно так должен вести себя счетный семафор .

Стандартный класс Semaphore не имеет способа ограничить количество разрешений.Если вы хотите блокировку (или двоичный семафор), вы должны использовать Lock класс ...


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

Да.Это было бы ошибкой в ​​приложении.

Теперь ... если вы хотите это обнаружить, вы можете расширить класс Semaphore и переопределить методы acquire и release, чтобы проверить, что числоразрешений остается между установленными границами.(Вы можете выдать непроверенное исключение, если проверка не удалась. Или вы можете молча проигнорировать запрос ... хотя это звучит как плохая идея.)

0 голосов
/ 05 декабря 2018

Почему он так себя ведет?

doc упоминает это:

При использовании таким образом, двоичный файлСемафор обладает свойством (в отличие от многих реализаций Lock), что «блокировка» может быть снята потоком, отличным от владельца (поскольку у семафоров нет понятия владения). Это может быть полезно в некоторых специализированных контекстах, таких как восстановление тупиковых ситуаций .


Вы можете использовать класс wrapper для отслеживания исходного разрешения.Но обычно он не должен вызывать release до тех пор, пока поток aquire не заблокируется, поэтому это не должно стать проблемой.

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