Если вы после минимизации головной боли, предпочитают мониторы (synchronized
блоки / методы) семафорам везде, где вы чувствуете реальный выбор блокирующего примитива.Игнорируйте академические разговоры о гибкости семафоров.Вы стремитесь к надежности, а не к конфигурируемости, не так ли?
Часто утверждают, что мониторы и семафоры эквивалентны (могут имитировать друг друга), но эта эквивалентность гораздо более абстрактна и менее полезна, чем иногда ожидается .Любой, кто может правильно смоделировать одно с другим, больше не нуждается в каком-либо ответе на этот вопрос.
Очевидно, что семафоры - ваш единственный практический выбор в ситуациях, когда разрешено число потоководновременно введите блок больше единицы.Таким образом, реальным конкурентом мониторов являются двоичные семафоры , а именно те, которые инициализируются со счетчиком 1, и дополнительно только те из них, где вы ожидаете, что тот же поток, который выполнял блокировку, в конечном итоге разблокирует семафор.Итак, давайте рассмотрим именно эти ситуации.
Принципиальное различие между мониторами и двоичными семафорами заключается в владении потоками .Это имеет большое значение, и это способность повторный вход .Повторный вход означает, что поток, который уже владеет блокировкой, может получить ее снова, в отличие от взаимоблокировки.Это имеет большое значение, если ваш класс имеет общее состояние, которое вы просто хотите защитить во всех методах, но не можете позволить себе постоянные предположения о том, как эти методы вызывают друг друга;или с любыми признаками пояса и фигурных скобок, которые развиваются в вашей схеме безопасности потоков в целом.
Семафоры никогда не возвращаются, а мониторы Java всегда возвращаются. Если вам нужно заблокировать один и тот же объект от многихместоположения кода, семафоры подвержены тупикам даже в однопоточных сценариях - и это ограничение семафоров дает какие-либо преимущества только в относительно редких сценариях, где мониторы в действительности не являются опцией.
Владение потокамитакже значительно снижает риск забывания блокировки, забывания разблокировки или действий одного потока, маскирующих действия другого потока.Существует также значительное эргономическое различие в связанном синтаксисе Java.
Обратите внимание также на этот вопрос ;хотя он использует другую терминологию, лучшие ответы там понимают «мьютекс», что означает «монитор» Java.