Что такое мьютекс и семафор в Java? В чем главное отличие? - PullRequest
105 голосов
/ 21 апреля 2009

Что такое мьютекс и семафор в Java? В чем главное отличие?

Ответы [ 11 ]

133 голосов
/ 22 апреля 2009

К сожалению, все упустили самое важное различие между семафором и мьютексом; понятие " владение ".

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

Мьютексы также могут поддерживать наследование приоритетов (что может помочь с проблемой инверсии приоритетов) и рекурсию (устранение одного типа взаимоблокировок).

Следует также отметить, что существуют "двоичные" семафоры и "счетные / общие" семафоры. Семафор Java является подсчитывающим семафором и, таким образом, позволяет инициализировать его значением больше единицы (тогда как, как указывалось, мьютекс может иметь только концептуальный счетчик единиц). Полезность этого была отмечена в других постах.

Итак, подведем итог: если у вас нет нескольких ресурсов для управления, я бы всегда рекомендовал мьютекс над семафором.

112 голосов
/ 21 апреля 2009

Семафор можно сосчитать, а мьютекс - только до 1.

Предположим, у вас запущен поток, который принимает клиентские соединения. Этот поток может обрабатывать 10 клиентов одновременно. Затем каждый новый клиент устанавливает семафор до тех пор, пока он не достигнет 10. Когда у семафора будет 10 флагов, ваш поток не будет принимать новые соединения

Мьютекс обычно используется для охраны вещей. Предположим, что ваши 10 клиентов могут получить доступ к нескольким частям системы. Затем вы можете защитить часть системы с помощью мьютекса, чтобы при подключении 1 клиента к этой подсистеме никто другой не имел доступа. Вы также можете использовать семафор для этой цели. Мьютекс - это "Семафор взаимного исключения" .

39 голосов
/ 21 апреля 2009

Мьютекс - это в основном взаимное исключение. Только один поток может получить ресурс одновременно. Когда один поток получает ресурс, никакому другому потоку не разрешается получать ресурс, пока поток, владеющий ресурсом, не освободится. Все потоки, ожидающие получения ресурса, будут заблокированы.

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

Короче говоря, главное отличие - сколько потоков может получить ресурс одновременно?

  • Мьютекс - это ОДИН.
  • Семафор - его DEFINED_COUNT, (столько же, сколько семафор)
8 голосов
/ 21 апреля 2009

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

3 голосов
/ 21 апреля 2009

Мьютекс часто называют двоичным семафором. Хотя семафор может быть создан с любым ненулевым счетом, мьютекс концептуально представляет собой семафор с верхним счетом 1.

3 голосов
/ 21 апреля 2009

Семафор - это механизм подсчета синхронизации, а мьютекс - нет.

2 голосов
/ 08 мая 2012

Этот вопрос имеет соответствующие ответы и ссылку на официальное руководство по Java: Есть ли в Java мьютекс?

0 голосов
/ 03 июля 2017

Семафор

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

Семафоры часто используются для ограничения количества потоков, которые могут получить доступ к некоторому (физическому или логическому) ресурсу

Java не имеет встроенного API Mutex. Но это может быть реализовано как двоичный семафор.

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

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

Итак ключевые различия между семафором и мьютексом:

  1. Семафор ограничивает количество потоков для доступа к ресурсу через разрешения. Mutex разрешает доступ к ресурсу только одному потоку.

  2. Нет тем, владеющих семафором. Потоки могут обновлять количество разрешений, вызывая методы acquire() и release(). Мьютексы должны быть разблокированы только нитью, удерживающей замок.

  3. Когда мьютекс используется с условными переменными, подразумевается заключение в скобки - ясно , какая часть программы защищена d. Это не обязательно относится к семафору, который можно назвать переходом к параллельному программированию - это мощный, но слишком простой в использовании неструктурированный, неопределенный способ.

0 голосов
/ 03 июля 2017

Объект синхронизации Семафор реализует классический светофор. Светофор контролирует доступ к ресурсу, который используется счетчиком. Если счетчик больше нуля, доступ предоставляется; Если он равен нулю, доступ запрещен. Счетчик подсчитывает разрешения, которые разрешают доступ к общему ресурсу. Затем для доступа к ресурсу поток должен получить разрешение от светофора. В общем, чтобы использовать светофор, поток, который хочет получить доступ к общему ресурсу, пытается получить разрешение. Если число светофоров больше нуля, поток получает разрешение, и количество светофоров уменьшается. В противном случае поток заблокирован, пока не получит разрешение. Когда потоку больше не требуется доступ к общему ресурсу, он освобождает разрешение, поэтому количество светофора увеличивается. Если есть другой поток, ожидающий разрешения, он получает разрешение в это время. Класс Java семафора реализует этот механизм.

Семафор имеет два строителя:

Semaphore(int num)
Semaphore(int num, boolean come)

num указывает начальный счет разрешения. Тогда num указывает количество потоков, которые могут получить доступ к общему ресурсу в данный момент времени. Если num равен единице, он может обращаться к ресурсу по одному потоку за раз. Установив come как true, вы можете гарантировать, что ожидающим потокам будет предоставлено разрешение в порядке их запроса.

0 голосов
/ 28 февраля 2017

Мьютекс - это двоичный семафор. Оно должно быть инициализировано 1, чтобы соблюдался принцип «первым пришел - первым обслужен». Это подводит нас к другому особому свойству каждого мьютекса: тот, кто сделал вниз , должен быть тем, кто up Поэтому мы получили взаимное исключение из-за какого-то ресурса.

Теперь вы можете видеть, что мьютекс является частным случаем общего семафора.

...