La synchronisation vs Verrouillage
java.util.concurrent
API fournit une classe appelée comme Lock
, qui aura pour sérialiser le contrôle afin d'accéder à la ressource critique. Il donne de la méthode telle que park()
et unpark()
.
Nous pouvons faire la même chose si nous pouvons utiliser synchronized
mot-clé et à l'aide de wait()
et notify() notifyAll()
méthodes.
Je me demande lequel des deux est mieux, dans la pratique, et pourquoi?
- article utile ici : javarevisited.blogspot.dans/2013/03/...
Vous devez vous connecter pour publier un commentaire.
Si vous êtes tout simplement le verrouillage d'un objet, je préfère utiliser
synchronized
Exemple:
Vous devez explicitement ne
try{} finally{}
partout.Alors qu'avec synchronisé, il est super clair et impossible de se tromper:
Cela dit,
Lock
s peut être plus utile à la plus compliquée des choses dont vous ne pouvez pas acquérir et de presse de telle manière propre. Je n'ai honnêtement préfèrent éviter nuesLock
s en premier lieu, et juste aller avec un plus sophistiqué de contrôle de la simultanéité comme unCyclicBarrier
ou unLinkedBlockingQueue
, s'ils répondent à vos besoins.Je n'ai jamais eu de raison d'utiliser
wait()
ounotify()
mais il y a peut être quelques bons.std::lock_guard
J'ai trouvé que
Lock
etCondition
(et d'autres nouvellesconcurrent
classes) sont juste plus d'outils de la boîte à outils. Je peut faire de plus tout ce que je voulais avec mon vieux marteau (lesynchronized
mot-clé), mais c'était difficile à utiliser dans certaines situations. Plusieurs de ces situations embarrassantes est devenu beaucoup plus simple une fois que j'ai ajouté plus d'outils à ma boîte à outils: un maillet en caoutchouc, un marteau à tête arrondie, un prybar, et certains clou à coups de poing. Cependant, mon vieux marteau voit encore sa part de l'utilisation.Je ne pense pas que l'on est vraiment "mieux" que l'autre, mais chacun d'eux est un meilleur ajustement pour des problèmes différents. En un mot, le modèle simple et à la portée tournée vers la nature de
synchronized
permet de me protéger d'un bug dans mon code, mais ces mêmes avantages sont parfois des obstacles dans des scénarios plus complexes. Sa ces des scénarios plus complexes que la concurrente de package a été créé pour aider à les résoudre. Mais l'utilisation de ce niveau élevé des constructions nécessite plus explicite et une gestion rigoureuse dans le code.===
Je pense que le JavaDoc fait un bon travail de décrire la distinction entre
Lock
etsynchronized
(l'emphase est mienne):Vous pouvez réaliser tout ce que les services publics en java.util.simultanées faire avec le faible niveau des primitives comme
synchronized
,volatile
, ou attendre /informerCependant, la concurrence est difficile, et la plupart des gens obtiennent au moins certaines parties de ce mal, ce qui rend leur code incorrect ou inefficace (ou les deux).
Simultanée de l'API offre un plus haut niveau de l'approche, qui est plus facile (et en tant que tel sûr) à utiliser. En un mot, vous ne devez pas utiliser
synchronized, volatile, wait, notify
plus directement.La Verrouillage classe elle-même est sur le niveau inférieur côté de cette boîte à outils, vous pouvez même pas besoin de l'utiliser directement (vous pouvez utiliser
Queues
et Sémaphore et des trucs, etc, la plupart du temps).java.util.concurrent
est plus facile [en général] que les fonctionnalités du langage (synchronized
, etc...). Lorsque vous utilisezjava.util.concurrent
vous avez à prendre l'habitude de remplirlock.lock(); try { ... } finally { lock.unlock() }
avant d'écrire le code alors qu'avec unsynchronized
vous êtes essentiellement amende dès le début. Sur cette seule base, je diraissynchronized
est plus facile (étant donné que vous voulez son comportement) quejava.util.concurrent.locks.Lock
. par 4Il existe 4 principaux facteurs pourquoi vous souhaitez utiliser
synchronized
oujava.util.concurrent.Lock
.Note: Synchronisation de verrouillage est ce que je veux dire quand je dis intrinsèque de verrouillage.
Lorsque Java 5 est sorti avec
ReentrantLocks, il s'avère qu'elles ont
tout à fait un noticeble débit
différence intrinsèque de verrouillage.
Si vous êtes à la recherche pour plus rapide de verrouillage
mécanisme et sont en cours d'exécution de 1,5
envisager j.u.c.ReentrantLock. Java
6 intrinsèque de verrouillage est maintenant
comparables.
j.u.c.Serrure a différents mécanismes
pour le verrouillage. Verrouillage interruptable -
tentative de verrouillage jusqu'à ce que le verrouillage
le thread est interrompu; chronométré de verrouillage
tentative de verrouillage pour un certain montant
et si vous n'avez pas
réussir; tryLock - tentative de verrouillage,
si un autre thread est tenue le
verrouillage de l'abandonner. Tout cela est inclus
en dehors de la simple serrure.
Intrinsèque verrouillage uniquement offre simple
verrouillage
dans les catégories de ce que vous êtes
concernées par la plupart des gens,
y compris moi-même, serait de trouver la
intrinsèque de verrouillage semenatics plus facile
à lire et moins verbeux alors
j.u.c.Serrure de verrouillage.
verrouillage ne peut être notifié et
attendu pour un seul cas. Lock
newCondition méthode permet de
seule Serrure avoir plusieurs raisons
d'attendre ou de signal. Je n'ai pas encore
vraiment besoin de cette fonctionnalité dans les
pratique, mais c'est une fonctionnalité intéressante pour les
ceux qui en ont besoin.
Je voudrais ajouter un peu plus de choses sur le dessus de Bert F réponse.
Locks
soutien de diverses méthodes pour la plus fine de verrouillage de contrôle, qui sont plus expressifs que implicites moniteurs (synchronized
serrures)Avantages de Serrure sur la Synchronisation à partir de la documentation page
L'utilisation de la synchronisation des méthodes ou des déclarations permet d'accéder à l'implicite moniteur de verrouillage associés à chaque objet, mais toutes les forces de verrouillage d'acquisition et de distribution de se produire dans un bloc structuré
De verrouillage implémentations de fournir des fonctionnalités supplémentaires par rapport à l'utilisation de la synchronisation des méthodes et des déclarations en fournissant un non-tentative de blocage pour acquérir un
lock (tryLock())
, une tentative d'acquérir le verrou qui peut être interrompu (lockInterruptibly()
, et une tentative d'acquérir le verrou qui peuttimeout (tryLock(long, TimeUnit))
.Un Verrou de classe peut également fournir comportement et de la sémantique qui est très différente de celle de l'implicite moniteur de verrouillage, tels que les de la garantie de la commande, non réentrant de l'utilisation, ou la détection de blocage
ReentrantLock: En termes simples, selon ma compréhension,
ReentrantLock
permet à un objet de re-saisir à partir d'une section critique à d'autres de la section critique . Puisque vous avez déjà serrure pour entrer dans une section critique, vous pouvez d'autres de la section critique sur le même objet à l'aide de verrouillage actuel.ReentrantLock
principales caractéristiques de ce l'articleVous pouvez utiliser
ReentrantReadWriteLock.ReadLock, ReentrantReadWriteLock.WriteLock
pour plus d'acquérir le contrôle granulaire de verrouillage sur les opérations de lecture et écriture.En dehors de ces trois ReentrantLocks, java 8 offre un Verrouillage
StampedLock:
Vous pouvez utiliser ces timbres soit de libérer un verrou ou pour vérifier si le verrou est toujours valide. En outre estampillés des verrous d'un autre mode de verrouillage appelé le verrouillage optimiste.
Jetez un oeil à cette l'article sur l'utilisation de différents types de
ReentrantLock
etStampedLock
serrures.La principale différence est l'équité, en d'autres mots, les demandes sont traitées FIFO ou peut-il aborder? Au niveau de la méthode de synchronisation assure juste ou FIFO répartition de la serrure. À l'aide de
ou
ne garantit pas l'équité.
Si vous avez beaucoup de contention pour le bloquer, vous pouvez facilement rencontrer irruption où des demandes plus récentes obtenir la serrure et des demandes plus anciennes coincé. J'ai vu des cas où 200 fils arrivent dans l'ordre court pour un verrou et le 2ème pour arriver a obtenu traité en dernier. C'est ok pour certaines applications, mais pour d'autres, c'est mortel.
Voir Brian Goetz "la Java de la Simultanéité Dans la Pratique" livre, section 13.3 pour une discussion complète sur ce sujet.
Brian Goetz "la Java de la Simultanéité Dans la Pratique," le livre, l'article 13.3:
"...Comme la valeur par défaut ReentrantLock, intrinsèque de verrouillage offre non déterministe de l'équité des garanties, mais l'
statistiques de l'équité des garanties de la plupart des implémentations de verrouillage sont assez bonnes pour presque toutes les situations..."
Verrou programmeurs vie plus facile. Voici quelques situations qui peuvent être atteints plus facilement avec serrure.
Tout, la serrure, et les conditions sont à construire sur la synchronisés. Alors certes vous pouvez achiever le même objectif avec qui. Toutefois, cela pourrait vous rendre la vie difficile et peut s'éloigner de vous de résoudre le problème.
Différence majeure entre l'écluse et synchronisé:
De verrouillage et de synchroniser bloquer les deux ont le même objectif, mais cela dépend de l'utilisation. Examiner le dessous de la partie
Dans le cas ci-dessus , si un fil entre le synchroniser bloc, l'autre bloc est également verrouillé. S'il y a plusieurs de ces synchroniser bloc sur le même objet, tous les blocs sont verrouillés. Dans de telles situations , java.util.de façon concomitante.La clé peut être utilisé pour empêcher les indésirables de verrouillage des blocs