2013-07-16 2 views
23

Я пытался понять блокировки ретентата и семафоры (гнездо реентера блокировки против механизма разблокировки/разблокировки).Двоичный семафор против ReentrantLock

Кажется, что с помощью Семафора вам нужно написать более тщательно протестированное приложение, потому что метод release() не проверяет, действительно ли поток, освобождающий разрешение, удерживает его. Когда я проверил свой тестовый код, я узнал, что это может впоследствии увеличить количество разрешений за пределы начального предела. С другой стороны, если поток не удерживает блокировку реентера, когда он вызывает метод разблокировки, мы получаем исключение IllegalMonitorException.

Итак, было бы правильно сказать, что нет никакой реальной причины иметь двоичный семафор, как все, что может сделать двоичный семафор, также может быть сделано ReentrantLock. Если мы используем двоичные семафоры, нам нужно будет проверить весь стек вызовов метода, чтобы узнать, было ли ранее получено разрешение (также оно было выпущено также, если есть возможность последующего приобретения), которое может блокироваться, если релиз его не запускает и скоро). Кроме того, поскольку реентеративные блокировки также обеспечивают одну блокировку для каждого объекта, не всегда ли лучше предпочитать блокировку реентера в двоичном семафоре?

Я проверил сообщение здесь, в котором говорится о различии между двоичным семафором и мьютексом, но есть ли что-то вроде мьютекса в Java?

Thanks, Chan.

P.S - Я разместил этот вопрос на другом форуме (http://www.coderanch.com/t/615796/threads/java/reason-prefer-binary-Semaphore-Reentrant), и я еще не получил ответа. Я думал, что отправлю его сюда, чтобы посмотреть, что я могу получить.

+0

http://stackoverflow.com/questions/12641933/difference-between-semaphore-and-condition-reentrantlock может помочь –

+2

Это поведение по дизайну и [хорошо документировано] (http://docs.oracle.com/) javase/7/docs/api/java/util/concurrent/Semaphore.html # release% 28% 29): «* Нет требования, чтобы поток, который освобождал разрешение, должен был получить это разрешение, вызвав метод получения(). использование семафора устанавливается с помощью соглашения о программировании в приложении. * ". При использовании ReentrantLocks вы должны обеспечить правильную освобождение блокировки в блоке finally. Это не соблюдается, но также хорошо документировано. – assylias

+1

См. Также: http://stackoverflow.com/questions/7554839/how-and-why-can-a-semaphore-give-out-more-permits-than-it-was-initialized-with – assylias

ответ

25

нет никакой реальной причины, когда-либо иметь двоичный семафор, как и все, что двоичный семафор может сделать также может быть сделано с помощью ReentrantLock

Если все, что вам нужно, это возвратный взаимное исключение, то да , нет причин использовать двоичный семафор над ReentrantLock. Если по какой-либо причине вам нужна семантика без права собственности, то очевидно, что семафор - ваш единственный выбор.

Кроме того, поскольку возвратные замки также обеспечивают один замок для каждого объекта, не правда ли всегда лучшая идея предпочитают замок возвратного в двоичный семафор?

Это зависит от необходимости. Как ранее объяснялось, если вам нужен простой мьютекс, тогда не выбирайте семафор. Если более чем один поток (но ограниченное число) может войти в критический раздел, вы можете сделать это через ограничение потока или семафор.

Я проверил почту здесь, что говорит о разнице между бинарным семафором и мьютексом, но есть вещи, как мьютекс в Java?

ReentrantLock и synchronized примеры мьютексы в Java.

+1

Спасибо, Джон. Это было быстро и полезно. – Chan

3

Я не буду объяснять блокировки повторного входа, так как Джон уже дал хорошее объяснение выше и его пример мьютекса в java вместе с ключевым словом Synchronized.

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

Еще один подход к вашей собственной реализации мьютекса с использованием java - LockSupport. Он немного похож на Семафор, но имеет время ожидания разрешения, используя функцию park() и поддерживает только одно разрешение в то время, в отличие от Семафоров, которые поддерживают несколько из них.

Смежные вопросы