Відповіді:
Семафор можна підрахувати, тоді як мютекс може нараховувати лише 1.
Припустимо, у вас працює потік, який приймає клієнтські з'єднання. Ця нитка може одночасно обробляти 10 клієнтів. Тоді кожен новий клієнт встановлює семафор, поки він не досягне 10. Коли у Semaphore є 10 прапорів, то ваша нитка не прийме нових з'єднань.
Mutex зазвичай використовують для охорони речей. Припустимо, ваші 10 клієнтів можуть отримати доступ до декількох частин системи. Тоді ви можете захистити частину системи за допомогою mutex, тому коли до цієї підсистеми підключено 1 клієнт, ніхто більше не повинен мати доступ. Для цього можна використовувати і семафор. Мутекс - це "Семафор взаємного виключення" .
ReentrantLock
. Все це є рекурсивними. Я не знаю жодних "реальних" прикладів нерекурсивних мютексів (я бачив їх лише у підручниках), тому я їх не розглядав.
На жаль, всі пропустили найважливішу різницю між семафором та мутекс; поняття " власність ".
Семафори не мають поняття власності, це означає, що будь-яка нитка може випустити семафор (це може призвести до багатьох проблем само по собі, але може допомогти у «виявленні смерті»). Тоді як у мютекс є поняття власності (тобто ви можете випустити лише придбаний мютекс).
Власність неймовірно важлива для безпечного програмування одночасних систем. Я завжди рекомендував би використовувати мутекс, віддаючи перевагу семафору (але є наслідки для продуктивності).
Mutexes також може підтримувати пріоритетне успадкування (що може допомогти з проблемою інверсії пріоритету) та рекурсію (усунення одного типу тупикової ситуації).
Слід також зазначити, що існують "бінарні" семафори та семафори "підрахунку / загального". Семафор Яви - це семафор лічильника і, таким чином, дозволяє його ініціалізувати зі значенням, більшим за одиницю (тоді як, як зазначалося, мютекс може мати лише концептуальний підрахунок одиниці). На корисність цього було вказано в інших посадах.
Отже, підводячи підсумок, якщо у вас є кілька ресурсів для управління, я б завжди рекомендував мутекс над семафором.
Mutex - це взагалі взаємне виключення. Лише одна нитка може отримати ресурс одночасно. Коли один потік набуває ресурс, жоден інший потік не може придбати ресурс, поки поток, що володіє ресурсом, не вивільниться. Усі потоки, які очікують на придбання ресурсу, будуть заблоковані.
Семафор використовується для контролю кількості виконуваних потоків. Буде закріплений набір ресурсів. Кількість ресурсів зменшуватиметься кожного разу, коли потоці належить те саме. Коли кількість семафорів досягає 0, жодним іншим потоком не дозволяється придбати ресурс. Нитки блокуються до випуску інших потоків, що володіють ресурсами.
Коротше кажучи, головна відмінність полягає в тому, скільки ниток дозволено придбати ресурс одночасно?
Мутекс використовується для послідовного доступу до ресурсу, тоді як семафор обмежує доступ до ресурсу до заданого числа. Ви можете думати про мутекс як про семафор з кількістю доступу 1. Що б ви не встановили підрахунок семафору, вони можуть отримати доступ до ресурсу до блокування ресурсу.
Семафор - це механізм підрахунку синхронізації, мютекс - ні.
На це питання є відповідні відповіді та посилання на офіційне керівництво Java: Чи є Mutex в Java?
Семафор :
Лічильний семафор. Концептуально семафор підтримує набір дозволів. Кожен
acquire()
блок, якщо необхідно, поки не буде дозволу, а потім бере його. Коженrelease()
додає дозвіл, потенційно звільняючи блокуючого набувача. Однак фактичні об’єкти дозволів не використовуються; Семафор просто зберігає підрахунок кількості наявних і діє відповідно.
Семафори часто використовуються для обмеження кількості потоків, ніж можуть отримати доступ до деякого (фізичного чи логічного) ресурсу
У Java немає вбудованого API Mutex. Але це може бути реалізовано як бінарний семафор.
Семафор, ініційований на один і який використовується таким чином, що у нього є щонайменше один дозвіл, може слугувати блокуванням взаємного виключення. Це більш відоме як двійковий семафор, оскільки він має лише два стани: один дозвіл доступний або нульовий дозвіл.
Використовуючи таким чином, бінарний семафор має властивість (на відміну від багатьох реалізацій Lock), що «замок» може бути звільнений потоком, відмінним від власника (оскільки семафори не мають поняття власності) . Це може бути корисно в деяких спеціалізованих контекстах, таких як відновлення тупикової ситуації.
Отже, ключові відмінності між Семафором та Мутексом:
Семафор обмежує кількість потоків для доступу до ресурсу через дозволи. Mutex дозволяє лише одному потоку отримати доступ до ресурсу.
Жодна нитка не володіє Семафором. Нитки можуть оновити кількість дозволів за допомогою виклику acquire()
та release()
методів. Мутекси повинні розмикатися лише ниткою, що тримає замок.
Коли використовується мютекс зі змінними стану, мається на увазі дужка - зрозуміло, яка частина програми захищається . Це необов'язково стосується семафору, який можна назвати переходом до паралельного програмування - це потужний, але занадто простий у використанні неструктурований, невизначений спосіб.
Mutex - це бінарний семафор. Він повинен бути ініціалізований з 1, щоб дотриматись принципу "Перший прихід". Це підводить нас до іншого особливому властивості кожного мьютекса: той , хто зробив вниз , повинен бути той , хто робить вгору . Ерго, ми отримали взаємне виключення за деякий ресурс.
Тепер ви могли бачити, що мютекс - це особливий випадок загального семафору.
Об'єкт синхронізації Семафорреалізує класичний світлофор. Світлофор керує доступом до ресурсу, спільним для лічильника. Якщо лічильник більше нуля, доступ надається; Якщо вона дорівнює нулю, доступ у користуванні заборонено Лічильник підраховує дозволи, які дозволяють отримати доступ до спільного ресурсу. Потім для доступу до ресурсу потік повинен отримати дозвіл від світлофора. Загалом, щоб використовувати світлофор, потік, який хоче отримати доступ до спільного ресурсу, намагається отримати дозвіл. Якщо кількість світлофора більше нуля, потік набуває дозволу, а кількість світлофорів зменшується. В іншому випадку нитка блокується, поки вона не отримає дозвіл. Коли потоці більше не потрібно отримувати доступ до спільного ресурсу, він видає дозвіл, тому кількість світлофорів збільшується. Якщо на дозвіл чекає інша нитка, вона набуває дозволу на той час. Клас Semaphore Java реалізує цей механізм.
Семафор має двох будівельників:
Semaphore(int num)
Semaphore(int num, boolean come)
num вказує початковий підрахунок дозволу. Тоді num вказує кількість потоків, які можуть отримати доступ до спільного ресурсу в даний момент часу. Якщо число є одиницею, воно може отримати доступ до ресурсу одночасно. Шляхом установки приходять як істинний, ви можете гарантувати , що нитки ви чекали надаються дозволи в порядку , вони просили.
Ви порівнюєте незрівнянне, технічно немає різниці між семафором і мютекс, це не має сенсу. Mutex - це просто значуща назва, як і будь-яке ім’я в логіці вашої програми, це означає, що ви ініціалізуєте семафор на "1", він використовується, як правило, для захисту ресурсу або захищеної змінної для забезпечення взаємного виключення.