Un sémaphore en Java est une aide à la synchronisation qui restreint le nombre de threads pouvant accéder à une ressource partagée à un moment donné. Il fait partie du package java.util.concurrent et est utilisé pour gérer l'accès simultané aux ressources, telles que les fichiers, les bases de données ou les connexions réseau.
Un sémaphore contrôle l'accès à un nombre défini de permis. Chaque permis représente le droit d’accéder à une ressource particulière. Le sémaphore garde une trace du nombre de permis disponibles, ce qui détermine le nombre de threads pouvant accéder simultanément à la ressource.
Permit : Un jeton ou un ticket qui permet à un thread de procéder à l'accès à une ressource partagée.
Lorsque vous créez un sémaphore, vous précisez le nombre de permis disponibles. Ce nombre définit le nombre de threads pouvant accéder simultanément à la ressource.
Avant qu'un thread puisse accéder à la ressource, il doit acquérir un permis du sémaphore. Cela se fait à l'aide de la méthode acquire().
Acquire : Cette méthode est appelée lorsqu'un thread souhaite accéder à la ressource. Si un permis est disponible, le sémaphore décrémente le nombre de permis disponibles et permet au thread de continuer. Si aucun permis n'est disponible, le thread est bloqué jusqu'à ce qu'un permis soit disponible.
Comportement de blocage : Si aucune autorisation n'est disponible, le thread qui appelle acquire() sera bloqué (c'est-à-dire qu'il attendra) jusqu'à ce qu'un autre thread libère une autorisation.
Une fois qu'un thread a fini d'utiliser la ressource, il doit libérer l'autorisation pour la rendre disponible pour d'autres threads. Cela se fait à l'aide de la méthode release().
Release : Cette méthode incrémente le nombre de permis disponibles. S'il y a des threads en attente d'un permis, l'un d'eux sera débloqué et autorisé à acquérir le permis.
Il existe deux types de sémaphores en Java :
Pour mieux comprendre le fonctionnement des sémaphores, examinons une implémentation pratique. Nous allons créer un scénario simple dans lequel plusieurs threads tentent d'accéder à une ressource limitée.
import java.util.concurrent.Semaphore; public class SemaphoreDemo { // Creating a semaphore with 3 permits private static final Semaphore semaphore = new Semaphore(3); public static void main(String[] args) { // Creating and starting 6 threads for (int i = 1; i2.2 Explication du Code
Dans cet exemple, nous créons un sémaphore avec trois autorisations, ce qui signifie que seuls trois threads peuvent accéder à la section critique du code à un moment donné. Nous créons ensuite six threads, qui tentent tous d'acquérir un permis. Une fois qu'un thread acquiert un permis, il simule un certain travail en dormant pendant deux secondes avant de libérer le permis.
2.3 Observation de la sortie
Lorsque vous exécutez le code ci-dessus, le résultat ressemblera à ceci :
Worker 1 is trying to acquire a permit... Worker 1 acquired a permit. Worker 2 is trying to acquire a permit... Worker 2 acquired a permit. Worker 3 is trying to acquire a permit... Worker 3 acquired a permit. Worker 4 is trying to acquire a permit... Worker 5 is trying to acquire a permit... Worker 6 is trying to acquire a permit... Worker 1 is releasing a permit. Worker 4 acquired a permit. Worker 2 is releasing a permit. Worker 5 acquired a permit. Worker 3 is releasing a permit. Worker 6 acquired a permit.Ici, les trois premiers threads acquièrent avec succès les permis et commencent leurs tâches. Les threads restants doivent attendre qu'une autorisation soit libérée avant de pouvoir continuer.
2.4 Cas d'utilisation pratique
Les sémaphores sont particulièrement utiles dans les scénarios où vous devez limiter le nombre d'accès simultanés à une ressource particulière, tels que :
Bien que les sémaphores soient un outil puissant, ils présentent leurs propres avantages et inconvénients.
Flexibilité : les sémaphores permettent un contrôle précis de l'accès aux ressources par plusieurs threads.
Évolutivité : Les sémaphores peuvent facilement gérer l'accès à un grand nombre de ressources.
Équité : les sémaphores peuvent être configurés pour garantir que les threads acquièrent les permis de manière équitable.
Complexité : l'utilisation de sémaphores peut introduire de la complexité dans votre code, ce qui rend le débogage plus difficile.
Deadlocks : S'ils ne sont pas gérés correctement, les sémaphores peuvent conduire à des blocages où les threads sont indéfiniment bloqués en attente d'autorisations.
Pour éviter les pièges courants et tirer le meilleur parti des sémaphores, tenez compte des bonnes pratiques suivantes :
Au lieu d'utiliser acquire(), qui bloque indéfiniment, vous pouvez utiliser tryAcquire() pour tenter d'acquérir un permis avec un délai d'attente. Cela empêche les fils de discussion de rester bloqués en attente.
if(semaphore.tryAcquire(1000, TimeUnit.MILLISECONDS)) { try { // Critical section } finally { semaphore.release(); } }
Pour éviter les fuites de ressources, libérez toujours le permis dans un bloc finalement. Cela garantit que le permis est libéré même en cas d'exception.
Si vous n'avez besoin de verrouiller et de déverrouiller une ressource que pour un seul thread, envisagez d'utiliser ReentrantLock ou synchronisé au lieu d'un sémaphore binaire.
Les sémaphores sont un outil puissant de gestion de la concurrence en Java, vous permettant de contrôler le nombre de threads accédant à une ressource partagée. En suivant les techniques et les bonnes pratiques décrites dans cet article, vous pouvez implémenter efficacement des sémaphores dans vos applications Java pour garantir une gestion sûre et efficace des ressources.
Si vous avez des questions ou souhaitez partager vos propres expériences avec les sémaphores, n'hésitez pas à commenter ci-dessous !
Lisez les articles plus sur : Techniques de gestion de la concurrence en Java à l'aide de sémaphores
Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.
Copyright© 2022 湘ICP备2022001581号-3