


Comment utiliser la file d'attente LinkedBlockingQueue dans la programmation simultanée Java ?
LinkedBlockingQueue est également implémenté à l'aide d'une liste chaînée unidirectionnelle. Il comporte également deux nœuds, qui sont utilisés respectivement pour stocker le premier et le dernier nœuds, et il existe également un nombre de variables atomiques avec une valeur initiale de 0, qui est utilisé pour enregistrer le nombre d'éléments de file d'attente. Il existe également deux instances de ReentrantLock, qui sont utilisées pour contrôler respectivement l'atomicité des éléments entrant et sortant de la file d'attente. Parmi elles, takeLock est utilisé pour contrôler qu'un seul thread peut obtenir des éléments de la tête de file d'attente en même temps, et que les autres threads doivent le faire. wait. PutLock contrôle qu'un seul thread peut obtenir des éléments de la tête de file d'attente en même temps. Un thread peut acquérir le verrou et ajouter des éléments à la fin de la file d'attente, et les autres threads doivent attendre. De plus, notEmpty et notFull sont des variables de condition. Elles disposent d'une file d'attente de conditions interne pour stocker les threads bloqués lors de l'entrée et de la sortie de la file d'attente. En fait, il s'agit du modèle producteur-consommateur. Voici le code pour créer un verrou exclusif.
private final AtomicInteger count = new AtomicInteger(); /** Lock held by take, poll, etc */ private final ReentrantLock takeLock = new ReentrantLock(); /** Wait queue for waiting takes */ private final Condition notEmpty = takeLock.newCondition(); /** Lock held by put, offer, etc */ private final ReentrantLock putLock = new ReentrantLock(); /** Wait queue for waiting puts */ private final Condition notFull = putLock.newCondition();
Lorsque le thread appelant effectue des opérations telles que prendre et interroger sur l'instance LinkedBlockingQueue, il doit obtenir le verrou takeLock pour garantir qu'un seul thread peut exploiter le nœud principal de la liste chaînée en même temps. De plus, étant donné que la maintenance de la file d'attente de conditions à l'intérieur de la variable de condition notEmpty utilise le mécanisme de gestion de l'état de verrouillage de takeLock, le thread appelant doit d'abord obtenir le verrou takeLock avant d'appeler les méthodes wait et signal de notEmpty, sinon une exception IllegalMonitorStateException sera levée. . NotEmpty maintient une file d'attente de conditions en interne Lorsque le thread acquiert le takeLock et appelle la méthode wait de notEmpty, le thread appelant sera bloqué, puis le thread sera placé dans la file d'attente de conditions à l'intérieur de notEmpty pour attendre qu'un thread appelle le signal notEmpty. méthode.
Lorsque vous effectuez des opérations put, offer et autres sur l'instance LinkedBlockingQueue, vous devez obtenir le verrou putLock pour vous assurer qu'un seul thread peut exploiter le nœud de queue de la liste chaînée en même temps. De même, puisque la maintenance de la file d'attente de conditions à l'intérieur de la variable de condition notFull utilise le mécanisme de gestion de l'état de verrouillage de putLock, le thread appelant doit d'abord acquérir le verrou putLock avant d'appeler les méthodes wait et signal de notFull, sinon une exception IllegalMonitorStateException sera levée. NotFull maintient une file d'attente de conditions en interne Lorsqu'un thread acquiert le verrou putLock et appelle la méthode wait de notFull, le thread appelant sera bloqué, puis le thread sera placé dans la file d'attente de conditions à l'intérieur de notFull pour attendre qu'un thread appelle notFull. méthode des signaux. Voici le code du constructeur sans paramètre de LinkedBlockingQueue.
Ce qui suit est le code de construction sans paramètre de LinkedBlockingQueue
public static final int MAX_VALUE = 0x7fffffff; public LinkedBlockingQueue() { this(Integer.MAX_VALUE); } public LinkedBlockingQueue(int capacity) { if (capacity <= 0) throw new IllegalAgrumentException(); this.capacity = capacity; last = head = new Node<E>(null); }
On peut voir à partir de ce code que la capacité de la file d'attente par défaut est 0x7fffffff, et les utilisateurs peuvent également spécifier eux-mêmes la capacité, donc dans une certaine mesure, cela peut être a déclaré que LinkedBlockingQueue est une file d'attente de blocage limitée.
offer operation
public boolean offer(E e) { //(1) if (e == null) throw new NullPointerException(); //(2) final AtomicInteger count = this.count; if (count.get() == capacity) return false; //(3) int c = -1; Node<E> node = new Node<E>(e); final ReentrantLock putLock = this.putLock; putLock.lock(); try { //(4) if (count.get() < capacity) { enqueue(node); c = count.getAndIncrement(); //(5) if (c + 1 < capacity) notFull.signal(); } } finally { //(6) putLock.unlock(); } //(7) if (c == 0) signalNotEmpty(); //(8) return c >= 0; }
Code (2) détermine si la file d'attente actuelle est pleine, supprime l'élément actuel et renvoie false
Code (3) obtient le verrou putLock Une fois que le thread actuel a obtenu le verrou, d'autres appels à. put et Le thread exploitant l'offre sera bloqué (le thread bloqué est placé dans la file d'attente de blocage AQS du verrou putLock).
Le code (4) réjuge ici si la file d'attente actuelle est pleine. En effet, d'autres threads peuvent avoir ajouté de nouveaux éléments à la file d'attente via des opérations put ou offer lors de l'exécution du code (2) et de l'acquisition du verrou putLock. . Si la file d'attente n'est effectivement pas pleine, de nouveaux éléments seront ajoutés à la file d'attente et le compteur sera incrémenté.
Le Code (5) détermine que s'il y a encore de l'espace libre dans la file d'attente après l'ajout du nouvel élément à la file d'attente, celui de la file d'attente conditionnelle qui réveille notFull est bloqué car l'opération d'attente de notFull est appelée (comme lorsque la méthode put est exécutée et que la file d'attente est pleine) Thread, parce que la file d'attente est maintenant inactive, un thread en file d'attente peut être réveillé à l'avance.
Le code (6) libère le verrou putLock acquis. Il convient de noter ici que le déverrouillage doit être effectué en final car même si le bloc try lève une exception, final sera exécuté. De plus, une fois le verrou libéré, l'un des autres threads bloqués par l'appel de l'opération put acquerra le verrou.
C0 dans le code (7) indique qu'il y a au moins un élément dans la file d'attente lors de l'exécution du code (6) pour libérer le verrou. S'il y a un élément dans la file d'attente, l'opération signalNotEmpty est exécutée.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Guide du nombre parfait en Java. Nous discutons ici de la définition, comment vérifier le nombre parfait en Java ?, des exemples d'implémentation de code.

Guide de Weka en Java. Nous discutons ici de l'introduction, de la façon d'utiliser Weka Java, du type de plate-forme et des avantages avec des exemples.

Guide du nombre de Smith en Java. Nous discutons ici de la définition, comment vérifier le numéro Smith en Java ? exemple avec implémentation de code.

Dans cet article, nous avons conservé les questions d'entretien Java Spring les plus posées avec leurs réponses détaillées. Pour que vous puissiez réussir l'interview.

Java 8 présente l'API Stream, fournissant un moyen puissant et expressif de traiter les collections de données. Cependant, une question courante lors de l'utilisation du flux est: comment se casser ou revenir d'une opération FOREAK? Les boucles traditionnelles permettent une interruption ou un retour précoce, mais la méthode Foreach de Stream ne prend pas directement en charge cette méthode. Cet article expliquera les raisons et explorera des méthodes alternatives pour la mise en œuvre de terminaison prématurée dans les systèmes de traitement de flux. Lire plus approfondie: Améliorations de l'API Java Stream Comprendre le flux Forach La méthode foreach est une opération terminale qui effectue une opération sur chaque élément du flux. Son intention de conception est

Guide de TimeStamp to Date en Java. Ici, nous discutons également de l'introduction et de la façon de convertir l'horodatage en date en Java avec des exemples.

Les capsules sont des figures géométriques tridimensionnelles, composées d'un cylindre et d'un hémisphère aux deux extrémités. Le volume de la capsule peut être calculé en ajoutant le volume du cylindre et le volume de l'hémisphère aux deux extrémités. Ce tutoriel discutera de la façon de calculer le volume d'une capsule donnée en Java en utilisant différentes méthodes. Formule de volume de capsule La formule du volume de la capsule est la suivante: Volume de capsule = volume cylindrique volume de deux hémisphères volume dans, R: Le rayon de l'hémisphère. H: La hauteur du cylindre (à l'exclusion de l'hémisphère). Exemple 1 entrer Rayon = 5 unités Hauteur = 10 unités Sortir Volume = 1570,8 unités cubes expliquer Calculer le volume à l'aide de la formule: Volume = π × r2 × h (4

Spring Boot simplifie la création d'applications Java robustes, évolutives et prêtes à la production, révolutionnant le développement de Java. Son approche "Convention sur la configuration", inhérente à l'écosystème de ressort, minimise la configuration manuelle, allo
