Je me demande lequel de ces deux est meilleur en pratique et pourquoi?
J'ai trouvé que Lock
et Condition
(et d'autres nouvelles classes concurrentes
) ne sont que d'autres outils dans la boîte à outils. Je pouvais faire à peu près tout ce dont j'avais besoin avec mon vieux marteau griffe (le mot-clé synchronized
), mais c'était gênant à utiliser dans certaines situations. Plusieurs de ces situations gênantes sont devenues beaucoup plus simples une fois que j'ai ajouté plus d'outils à ma boîte à outils : un maillet en caoutchouc, un marteau à panne ronde, un pied-de-biche, et des chasse-clous. Cependant, mon vieux marteau griffe voit encore son lot d'utilisation.
Je ne pense pas qu'un soit vraiment "meilleur" que l'autre, mais plutôt que chacun convient mieux à différents problèmes. En un mot, le modèle simple et la nature orientée vers la portée de synchronized
m'aident à me protéger des bugs dans mon code, mais ces mêmes avantages sont parfois des obstacles dans des scénarios plus complexes. Ce sont ces scénarios plus complexes pour lesquels le package concurrent a été créé pour aider à résoudre. Mais l'utilisation de ces constructions de niveau supérieur nécessite une gestion plus explicite et soigneuse dans le code.
\===
Je pense que le JavaDoc fait un bon travail pour décrire la distinction entre Lock
et synchronized
(l'accent est mis sur moi):
Les implémentations de Lock fournissent des opérations de verrouillage plus étendues que celles obtenues avec des méthodes et des instructions synchronisées. Elles permettent une structuration plus flexible, peuvent avoir des propriétés très différentes, et peuvent prendre en charge plusieurs objets Condition associés.
...
L'utilisation de méthodes synchronisées ou d'instructions donne accès au verrou implicite associé à chaque objet, mais force l'acquisition et la libération des verrous à se produire de manière structurée par bloc : lorsque plusieurs verrous sont acquis ils doivent être libérés dans l'ordre inverse, et tous les verrous doivent être libérés dans la même portée lexicale dans laquelle ils ont été acquis.
Alors que le mécanisme de portée pour les méthodes et instructions synchronisées rend beaucoup plus facile de programmer avec des verrous de moniteur, et aide à éviter de nombreuses erreurs de programmation courantes impliquant des verrous, il y a des occasions où vous devez travailler avec des verrous de manière plus flexible. Par exemple, **certains algorithmes* pour traverser des structures de données accessibles de manière concurrente nécessitent l'utilisation de "verrouillage main dans la main" ou "verrouillage en chaîne" : vous acquérez le verrou du nœud A, puis du nœud B, puis relâchez A et acquérez C, puis relâchez B et acquérez D et ainsi de suite. Les implémentations de l'interface Lock permettent l'utilisation de telles techniques en permettant l'acquisition et la libération d'un verrou dans des portées différentes, et permettant l'acquisition et la libération dans n'importe quel ordre de plusieurs verrous.
Avec cette flexibilité accrue vient une responsabilité supplémentaire. L'absence de verrouillage structuré par bloc supprime la libération automatique des verrous qui se produit avec les méthodes et instructions synchronisées. Dans la plupart des cas, l'idiome suivant devrait être utilisé:
...
Lorsque le verrouillage et le déverrouillage se produisent dans des portées différentes, il faut veiller à s'assurer que tout le code qui est exécuté pendant que le verrou est détenu est protégé par un bloc try-finally ou try-catch pour assurer que le verrou est libéré quand nécessaire.
Les implémentations de Lock fournissent des fonctionnalités supplémentaires par rapport à l'utilisation de méthodes et instructions synchronisées en fournissant une tentative de verrouillage non bloquante (tryLock()), une tentative de verrouillage qui peut être interrompue (lockInterruptibly()), et une tentative de verrouillage qui peut expirer (tryLock(long, TimeUnit)).
...
1 votes
Article utile ici : javarevisited.blogspot.in/2013/03/…