Страницы

Поиск по вопросам

четверг, 28 ноября 2019 г.

Что такое монитор, мьютекс и семафор? Это одно и тоже или разные вещи?

#java #многопоточность


Просто везде написано по-разному. И никак не могу понять, что по сути обозначает
каждое из этих понятий. Например, у того же Эккеля есть такие строчки про это:


  Для решения проблемы соперничества потоков фактически все многопоточные схемы синхронизируют
доступ к разделяемым ресурсам. Это означает, что доступ к разделяемому ресурсу в один
момент времени может получить только один поток. Чаще всего это выполняется помещением
фрагмента кода в секцию блокировки так, что одновременно пройти по этому фрагменту
кода может только один поток. Поскольку такое предложение блокировки дает эффект взаимного
исключения, этот механизм часто называют мьютексом (MUTual Exclusion). 
  
  В Java есть встроенная поддержка для предотвращения конфликтов в виде
  ключевого слова synchronized. Когда поток желает выполнить фрагмент
  кода, охраняемый словом synchronized, он проверяет, доступен ли
  семафор, получает доступ к семафору, выполняет код и освобождает
  семафор.


Сам я читал в одной статье (и пока придерживаюсь этого понимания), что мьютекс -
это некий объект, который связан с каждым объектом в Джава, и который может принимать
два состояния: занят и свободен. А про монитор в той же статей было написано, что это
некий специальный механизм (по сути - кусок кода), который, используя мьютекс, регулирует
доступ нитей к некоторому блоку кода (то есть он отвечает за захват нити ресурса, и
позволяет только одной данной нити (которая захватила мьютекс) идти по данному, охраняемому
монитором, блоку кода; соответственно, другим нитям монитор не даёт занять этот ресурс
и этот блок кода; а когда нить выходит из этого блока кода, то монитор освобождает
мьютекс и позволяет другим нитям войти в этот блок кода). Это правильное понимание?

А что конкретно обозначают эти понятия в Джаве?
    


Ответы

Ответ 1



В целом, можно считать, что мютекс это частный случай семафора. Семафор работает просто - у него есть некое начальное число - счетчик. Каждый раз, когда какой то поток "захватывает" семафор, это число уменьшается на единицу. Если оно равно нулю или меньше нуля - семафор запирается (то есть, грубо говоря, код останавливается на моменте захвата семафора). Каждый раз, когда семафор освобождается - этот счетчик увеличивается на единицу. И если он после этого окажется больше нуля, то какому то произвольному потоку, который "висит на захвате семафора" будет послан сигнал на пробуждение и он сможет продолжить работу (естественно, снова уменьшив значение счетчика). Самый очевидный пример семафора - это менеджеры закачек - добавляем много файлов на закачку, но ограничиваем количество одновременных скачек. А мютекс - это просто семафор, который инициализирован начальным числом 1. Поэтому, только один поток может его захватить. Но как всегда, есть исключения. Есть так называемые мютексы на чтение-запись (RWLock). Эти мютексы можно захватывать на чтение и на запись. И если на чтение может захватить много потоков, то на запись - только один (да, и в этот момент больше никто не может читать). что мьютекс - это некий объект, который связан с каждым объектом в Джава, и который может принимать два состояния: занят и свободен. это почти близко к истине. Да, в java у класса Object есть поле типа мютекс. И все наследники (читай все остальные классы) также получают персональный мютекс. если метод пометить словом syncronized, то это просто заворачивает его вызов в этот мютекс. То есть, если вызывать syncronized методы у одного объекта с разных потоков - мютекс не даст им выполнятся параллельно. Но для разных объектов (даже одного типа) это уже не работает.

Комментариев нет:

Отправить комментарий