web-dev-qa-db-fra.com

Qu'est-ce que mutex et sémaphore en Java? Quelle est la différence principale?

Qu'est-ce que mutex et sémaphore en Java? Quelle est la différence principale?

104
Tony

Le sémaphore peut être compté, alors que le mutex ne peut compter que pour 1.

Supposons que vous avez un thread en cours d'exécution qui accepte les connexions client. Ce fil peut gérer 10 clients simultanément. Chaque nouveau client définit ensuite le sémaphore jusqu'à ce qu'il atteigne 10. Lorsque le sémaphore a 10 indicateurs, votre thread n'accepte pas les nouvelles connexions.

Les mutex sont généralement utilisés pour garder des objets. Supposons que vos 10 clients puissent accéder à plusieurs parties du système. Ensuite, vous pouvez protéger une partie du système avec un mutex. Ainsi, lorsqu'un client est connecté à ce sous-système, personne d'autre ne devrait y avoir accès. Vous pouvez également utiliser un sémaphore à cette fin. Un mutex est un "Sémaphore d'exclusion mutuelle" .

112
Eric

Malheureusement, tout le monde a oublié la différence la plus importante entre le sémaphore et le mutex; le concept de " propriété ". 

Les sémaphores n'ont pas de notion de propriété, cela signifie que n'importe quel fil peut libérer un sémaphore (cela peut poser de nombreux problèmes en soi mais peut aider à la "détection de la mort"). Alors qu’un mutex a bien le concept de propriété (c’est-à-dire que vous ne pouvez libérer qu’un mutex que vous avez acquis).
La propriété est extrêmement importante pour la programmation en toute sécurité des systèmes concurrents. Je recommanderais toujours d'utiliser mutex de préférence à un sémaphore (mais il y a des implications sur les performances). 

Les mutex peuvent également prendre en charge l'héritage des priorités (qui peut aider à résoudre le problème d'inversion des priorités) et la récursivité (en éliminant un type d'impasse). 

Il convient également de noter qu'il existe des sémaphores "binaires" et des sémaphores "comptage/général". Le sémaphore de Java est un sémaphore de comptage et permet ainsi son initialisation avec une valeur supérieure à un (alors que, comme indiqué, un mutex ne peut compter que de manière conceptuelle). L'utilité de ceci a été soulignée dans d'autres articles. 

Donc, pour résumer, à moins que vous n'ayez plusieurs ressources à gérer, je recommanderais toujours le mutex au-dessus du sémaphore. 

131
feabhas

Mutex est fondamentalement une exclusion mutuelle. Un seul thread peut acquérir la ressource à la fois. Lorsqu'un thread acquiert la ressource, aucun autre thread n'est autorisé à acquérir la ressource jusqu'à ce que le thread propriétaire de la ressource soit libéré. Tous les threads en attente d'acquisition de ressource seraient bloqués.

Semaphore est utilisé pour contrôler le nombre de threads en cours d'exécution. Il y aura un ensemble fixe de ressources. Le nombre de ressources sera décrémenté chaque fois qu'un thread possède le même. Lorsque le nombre de sémaphores atteint 0, aucun autre thread n'est autorisé à acquérir la ressource. Les threads sont bloqués jusqu'à ce que d'autres threads possèdent des versions de ressources.

En bref, la principale différence est combien de threads sont autorisés à acquérir la ressource en même temps?  

  • Mutex - son UN.
  • Sémaphore - son DEFINED_COUNT, (autant que le nombre de sémaphores)
38
aJ.

Un mutex est utilisé pour un accès en série à une ressource, tandis qu'un sémaphore limite l'accès à une ressource jusqu'à un nombre défini. Vous pouvez considérer un mutex comme un sémaphore avec un nombre d'accès égal à 1. Quelle que soit la définition du nombre de sémaphores, les threads peuvent accéder à la ressource avant que celle-ci ne soit bloquée.

8
Jason Coco

Un sémaphore est un mécanisme de synchronisation de comptage, pas un mutex. 

3
Brian Rasmussen

Un mutex est souvent appelé sémaphore binaire. Alors qu'un sémaphore peut être créé avec un nombre différent de zéro, un mutex est un séméphore avec un nombre supérieur de 1.

3
Sean

Cette question a des réponses pertinentes et un lien vers les directives officielles de Java: Existe-t-il un Mutex en Java?

2
Air

Vous comparez l'incomparable, techniquement, il n'y a pas de différence entre un sémaphore et un mutex, cela n'a pas de sens . Mutex est juste un nom significatif comme tout nom dans votre logique d'application, cela signifie que vous initialisez un sémaphore à "1" Il est généralement utilisé pour protéger une ressource ou une variable protégée afin d’assurer l’exclusion mutuelle.

0
Marwen Trabelsi

Sémaphore :

Un sémaphore de comptage. Conceptuellement, un sémaphore conserve un ensemble de permis. Chaque acquire() bloque si nécessaire jusqu'à ce qu'un permis soit disponible, puis le prend. Chaque release() ajoute un permis, libérant éventuellement un acquéreur bloquant. Cependant, aucun objet de permis réel n'est utilisé; le sémaphore conserve simplement un compte du nombre disponible et agit en conséquence.

Les sémaphores sont souvent utilisés pour limiter le nombre de threads pouvant accéder à certaines ressources (physiques ou logiques)

Java n'a pas d'API Mutex intégrée. Mais il peut être implémenté sous forme de sémaphore binaire.

Un sémaphore initialisé à un, et utilisé de telle sorte qu'il ne dispose que d'un seul permis disponible, peut servir de verrou d'exclusion mutuelle. Ceci est plus communément appelé sémaphore binaire, car il n'a que deux états: un permis disponible ou aucun permis disponible. 

Utilisé de cette manière, le sémaphore binaire a la propriété (contrairement à de nombreuses implémentations de Lock), que le "verrou" peut être libéré par un thread autre que le propriétaire (les sémaphores n’ayant pas de notion de propriété)}. Cela peut être utile dans certains contextes spécialisés, tels que la reprise dans l'impasse.

So différences clés entre Semaphore et Mutex:

  1. Semaphore limite le nombre de threads pour accéder à une ressource via des permis. Mutex n'autorise qu'un seul thread à accéder à la ressource.

  2. Aucun fil ne possède Semaphore. Les threads peuvent mettre à jour le nombre de permis en appelant les méthodes acquire() et release(). Les mutex ne doivent être déverrouillés que par le fil qui tient le verrou.

  3. Lorsqu'un mutex est utilisé avec des variables de condition, il existe un crochet implicite: il est clair que quelle partie du programme est en cours de protection d. Ce n'est pas nécessairement le cas pour un sémaphore, que l'on pourrait appeler le passer à la programmation concurrente - il est puissant mais trop facile à utiliser de manière non structurée et indéterminée.

0
Ravindra babu

Mutex est un sémaphore binaire. Il doit être initialisé avec 1 pour que le principe du premier arrivé, premier servi soit respecté. Cela nous amène à l’autre propriété spéciale de chaque mutex: celui qui a fait down , doit être celui qui fait up. Nous avons donc obtenu une exclusion mutuelle pour certaines ressources. 

Vous pouvez maintenant voir qu'un mutex est un cas particulier de sémaphore général.

0
Kод it

L'objet de synchronisation Semaphore implémente un feu de signalisation classique. Un feu de signalisation contrôle l'accès à une ressource partagée par un compteur. Si le compteur est supérieur à zéro, l'accès est accordé. S'il est nul, l'accès est refusé. Le compteur compte les autorisations permettant d'accéder à la ressource partagée. Ensuite, pour accéder à la ressource, un thread doit recevoir l’autorisation du témoin de trafic. En général, pour utiliser un feu de signalisation, le thread qui souhaite accéder à la ressource partagée tente d'acquérir un permis. Si le nombre de feux de signalisation est supérieur à zéro, le thread obtient un permis et le nombre de feux de signalisation est décrémenté. Sinon, le thread est verrouillé jusqu'à ce qu'il puisse obtenir une autorisation. Lorsque le thread n'a plus besoin d'accéder à la ressource partagée, il libère l'autorisation. Le nombre de feux de signalisation est donc augmenté. S'il y a un autre thread en attente d'un permis, il l'obtient à ce moment-là. La classe Semaphore de Java implémente ce mécanisme. 

Semaphore a deux constructeurs:

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

num spécifie le décompte initial du permis. Ensuite, num spécifie le nombre de threads pouvant accéder à une ressource partagée à un moment donné. Si num est un, il peut accéder à la ressource un thread à la fois. En définissant come sur true, vous pouvez garantir que les threads que vous attendez obtiendront les autorisations dans l'ordre demandé.

0
Amarildo