Cet article présente principalement en détail les informations pertinentes sur le verrouillage de concurrence Java, qui ont une certaine valeur de référence. Les amis intéressés peuvent se référer à
Selon le moment où le verrou est ajouté à Java, les verrous en Java peuvent. être divisé en « verrous de synchronisation » et « verrous dans le package JUC ».
Verrouillage de synchronisation
Autrement dit, la synchronisation est effectuée via le mot-clé synchronisé pour obtenir un accès mutuellement exclusif aux ressources concurrentes. Les verrous de synchronisation sont déjà pris en charge dans Java 1.0.
Le principe du verrou de synchronisation est que pour chaque objet , il n'y a qu'un seul verrou de synchronisation, différents threads peuvent accéder conjointement au verrou de synchronisation ; Cependant, au même moment, le verrou de synchronisation ne peut et ne peut être acquis que par un seul thread. De cette manière, les threads qui ont obtenu le verrou de synchronisation peuvent être planifiés par le CPU et exécutés sur le CPU ; les threads qui n'ont pas obtenu le verrou de synchronisation doivent attendre d'obtenir le verrou de synchronisation avant de pouvoir continuer à s'exécuter. C'est le principe de la synchronisation multi-thread grâce au verrouillage de synchronisation !
Le verrou dans le package JUC
Par rapport au verrou de synchronisation, la fonction du verrou dans le package JUC est plus puissante. fournit un Framework, qui permet une utilisation plus flexible des verrous, mais est plus difficile à utiliser.
Les verrous du package JUC incluent : Lockinterface, interface ReadWriteLock, primitive de blocage LockSupport, condition de condition, AbstractOwnableSynchronizer/AbstractQueuedSynchronizer/AbstractQueuedLongSynchronizer trois classes abstraites , Verrou exclusif ReentrantLock, Verrouillage en lecture-écriture ReentrantReadWriteLock. Puisque CountDownLatch, CyclicBarrier et Semaphore sont également implémentés via AQS, je vais donc également les introduire dans le framework de verrouillage ;
Regardez d'abord le schéma du cadre de la serrure, comme indiqué ci-dessous.
01. Interface de verrouillage
L'interface de verrouillage du package JUC prend en charge ceux avec règles de verrouillage sémantiques différentes (Réentrance, équité, etc.). La sémantique dite différente signifie que les verrous peuvent inclure des « verrous à mécanisme équitable », des « verrous à mécanisme injuste », des « verrous réentrants », etc. "Mécanisme équitable" fait référence à "le mécanisme permettant aux différents threads d'acquérir des verrous est juste", tandis que "mécanisme injuste" fait référence à "le mécanisme permettant à différents threads d'acquérir des verrous est injuste", et "verrouillage réentrant" fait référence au même mécanisme. être acquis plusieurs fois par un thread.
02. ReadWriteLock
L'interface ReadWriteLock définit un certain nombre de lecteurs qui peuvent être partagés de la même manière que Verrouillage exclusif à Writer. Une seule classe du package JUC implémente cette interface, ReentrantReadWriteLock, car elle convient à la plupart des contextes d'utilisation standard. Mais les programmeurs peuvent créer leurs propres implémentations adaptées aux exigences non standard.
03. AbstractOwnableSynchronizer/AbstractQueuedSynchronizer/AbstractQueuedLongSynchronizer
AbstractQueuedSynchronizer est une classe appelée AQS, c'est une superclasse très utile. pour définir des verrous et d'autres synchroniseurs qui reposent sur la mise en file d'attente des threads bloqués ; des classes telles que ReentrantLock, ReentrantReadWriteLock, CountDownLatch, CyclicBarrier et Semaphore sont toutes implémentées sur la base de la classe AQS. La classe AbstractQueuedLongSynchronizer fournit la même fonctionnalité mais étend la prise en charge de l'état de synchronisation 64 bits. Les deux étendent la classe AbstractOwnableSynchronizer (une classe simple qui permet de savoir quel thread maintient actuellement la synchronisation exclusive).
04. LockSupport
LockSupport fournit "créer des verrous" et des "primitives de base de blocage de threads pour d'autres classes de synchronisation".
La fonction de LockSupport est quelque peu similaire à "Thread.suspend() et Thread.resume() dans Thread". Les fonctions de park() et unpark() dans LockSupport sont de bloquer les threads et relâchez-les respectivement. Bloquez le fil. Cependant, park() et unpark() ne rencontreront pas le problème de « blocage pouvant être causé par Thread.suspend et Thread.resume ».
05. Etat
Condition doit être utilisé en conjonction avec Lock. Sa fonction est de remplacer la méthode de surveillance Object Vous pouvez mettre en veille/réveiller les threads via wait() et signal(). L'interface
Condition décrit les variables de condition qui peuvent être associées au verrou. Ces variables sont similaires dans leur utilisation aux moniteurs implicites accessibles à l'aide de Object.wait, mais offrent des fonctionnalités plus puissantes. Il est important de noter qu’un seul verrou peut être associé à plusieurs objets Condition. Pour éviter les problèmes de compatibilité, les noms des méthodes Condition sont différents de ceux de la version Object correspondante.
06. ReentrantLock
ReentrantLock est un verrou exclusif. Le verrou dit exclusif fait référence à un verrou qui ne peut être occupé que par lui-même, c'est-à-dire qu'il ne peut être acquis que par un seul thread lock au même moment. Les verrous ReentrantLock incluent « ReentrantLock équitable » et « ReentrantLock injuste ». "Fair ReentrantLock" signifie "le mécanisme permettant aux différents threads d'acquérir des verrous est équitable", tandis que "unfair ReentrantLock" signifie "le mécanisme permettant aux différents threads d'acquérir des verrous est injuste", et ReentrantLock est un "verrou réentrant".
Le diagramme de classes UML de ReentrantLock est le suivant :
(01) ReentrantLock implémente l'interface Lock.
(02) Il existe une variable membre sync dans ReentrantLock, sync est le type Sync ; Sync est une classe abstraite et elle hérite d'AQS.
(03) Il existe une « classe de verrouillage équitable » FairSync et une « classe de verrouillage injuste » NonfairSync dans ReentrantLock, qui sont toutes deux des sous-classes de Sync. L'objet de synchronisation dans ReentrantReadWriteLock est l'un des FairSync et NonfairSync. Cela signifie également que ReentrantLock est l'un des "verrouillage équitable" ou "verrouillage injuste" par défaut.
07. ReentrantReadWriteLock
ReentrantReadWriteLock est la classe d'implémentation de l'interface de verrouillage en lecture-écriture ReadWriteLock, qui comprend les sous-classes ReadLock. et WriteLock. ReentrantLock est un verrou partagé, tandis que WriteLock est un verrou exclusif.
Le diagramme de classes UML de ReentrantReadWriteLock est le suivant :
(01) ReentrantReadWriteLock implémente l'interface ReadWriteLock.
(02) ReentrantReadWriteLock contient un objet de synchronisation, un verrou de lecture readerLock et un verrou d'écriturewriterLock. Le verrou de lecture ReadLock et le verrou d'écriture WriteLock implémentent tous deux l'interface Lock.
(03) Comme "ReentrantLock", sync est de plus un type Sync, Sync est aussi une classe abstraite héritée d'AQS ; La synchronisation inclut également le « verrouillage équitable » FairSync et le « verrouillage injuste » NonfairSync.
08. CountDownLatch
CountDownLatch est une classe d'assistance à la synchronisation qui effectue un ensemble d'opérations en cours d'exécution dans d'autres threads auparavant. Il permet à un ou plusieurs threads d'attendre indéfiniment.
Le diagramme de classes UML de CountDownLatch est le suivant :
CountDownLatch contient l'objet sync, et sync est le type Sync. Sync de CountDownLatch est une classe d'instance qui hérite d'AQS.
09. CyclicBarrier
CyclicBarrier est une classe auxiliaire de synchronisation qui permet à un groupe de threads de s'attendre les uns les autres. jusqu'à un certain point de barrière commun. Étant donné que cette barrière peut être réutilisée une fois le thread en attente libéré, on l'appelle une barrière de boucle.
Le diagramme de classes UML de CyclicBarrier est le suivant :
CyclicBarrier inclut le "verrouillage d'objet ReentrantLock" et le "déclenchement d'objet de condition" . Il est mis en œuvre via des verrous exclusifs.
La différence entre CyclicBarrier et CountDownLatch est :
(01) La fonction de CountDownLatch est de permettre à 1 ou N threads d'attendre que d'autres threads terminent leur exécution ; tandis que CyclicBarrier permet à N threads de s'attendre les uns les autres.
(02) Le compteur de CountDownLatch ne peut pas être réinitialisé ; le compteur de CyclicBarrier peut être réinitialisé et utilisé, c'est pourquoi on l'appelle une barrière cyclique.
10. Sémaphore
Le sémaphore est un sémaphore comptant, son essence est un "serrure partagée".
Un sémaphore maintient un ensemble d'autorisations de sémaphore. Le thread peut obtenir l'autorisation du sémaphore en appelant acquire(); lorsqu'il y a une autorisation disponible dans le sémaphore, le thread peut obtenir l'autorisation sinon, le thread doit attendre qu'il y ait une autorisation disponible ; Un thread peut libérer la licence de sémaphore qu'il détient via release().
Le diagramme de classes UML de Semaphore est le suivant :
Identique à "ReentrantLock", Semaphore contient des objets de synchronisation, sync est un type Sync et, Sync est également une classe abstraite héritée d'AQS. Sync inclut également le « sémaphore équitable » FairSync et le « sémaphore injuste » NonfairSync.
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!