Quelle est la différence entre une méthode synchronisée et un bloc synchronisé en Java? [dupliquer]
cette question a déjà une réponse ici:
Quelle est la différence entre une méthode synchronisée et un bloc synchronisé en Java ?
j'ai été cherchant la réponse sur le Net, les gens semblent être si incertains à propos de celui-ci: - (
mon point de vue serait qu'il n'y a pas de différence entre les deux, sauf que le bloc de synchronisation pourrait être plus localisée dans la portée et donc la serrure sera de moins de temps ??
et en cas de verrouillage sur une méthode statique, sur quoi prend la serrure ? Quelle est la signification d'un verrou sur la classe ?
6 réponses
une méthode synchronisée utilise le récepteur de méthode comme une serrure (i.e. this
pour les méthodes non statiques, et la classe enveloppante pour les méthodes statiques). Synchronized
blocks utilise l'expression comme une serrure.
les deux méthodes suivantes sont donc équivalentes à la méthode prospective de verrouillage:
synchronized void mymethod() { ... }
void mymethod() {
synchronized (this) { ... }
}
pour les méthodes statiques, la classe sera verrouillée:
class MyClass {
synchronized static mystatic() { ... }
static mystaticeq() {
syncrhonized (MyClass.class) { ... }
}
}
pour les blocs synchronisés, vous pouvez utiliser n'importe quel Non - null
objet comme Serrure:
synchronized (mymap) {
mymap.put(..., ...);
}
Lock portée
pour les méthodes synchronisées, la serrure sera maintenue tout au long du champ d'application de la méthode, tandis que dans le bloc synchronized
, la serrure ne sera maintenue que pendant le champ d'application de ce bloc (aussi appelé section critique). En pratique, la JVM est autorisée à optimiser en retirant certaines opérations de l'exécution du bloc synchronized
si elle peut prouver qu'elle peut être effectuée en toute sécurité.
une méthode synchronisée est abrégée. Ceci:
class Something {
public synchronized void doSomething() {
...
}
public static synchronized void doSomethingStatic() {
...
}
}
est, à toutes fins pratiques, équivalent à ceci:
class Something {
public void doSomething() {
synchronized(this) {
...
}
}
public static void doSomethingStatic() {
synchronized(Something.class) {
...
}
}
}
(où Something.class
est l'objet de la classe Something
.)
donc en effet, avec un bloc synchronisé, vous pouvez être plus précis à propos de votre serrure, et plus précis sur le moment où vous voulez l'utiliser, mais à part ça, il n'y a aucune différence.
Oui, c'est une différence. L'autre est que vous pouvez acquérir une serrure sur d'autres objets que this
.
la différence clé est celle-ci: si vous déclarez qu'une méthode doit être synchronisée, alors le corps entier de la méthode devient synchronisé; si vous utilisez le bloc synchronisé, cependant, vous pouvez entourer juste la" section critique " de la méthode dans le bloc synchronisé, tout en laissant le reste de la méthode en dehors du bloc.
si l'ensemble de la méthode fait partie de la section critique, alors il n'y a effectivement aucune différence. Si ce n'est pas le cas, alors vous devriez utilisez un bloc synchronisé autour de la section critique. Plus vous avez de déclarations dans un bloc synchronisé, moins vous obtenez de parallélisme global, donc vous voulez les garder au minimum.
une méthode synchronisée se bloque sur l'instance de l'objet dans laquelle la méthode est contenue.
où comme un bloc synchronisé peut se verrouiller sur N'importe quel objet - typiquement un obect mutex défini comme une variable d'instance. Cela permet plus de contrôle sur ce que les serrures sont en fonctionnement.
mon point de vue serait qu'il n'y a pas de différence entre les deux, sauf que le bloc de synchronisation pourrait être plus localisé dans la portée et donc la serrure sera de moins de temps ??
Oui. Vous êtes de droite. Contrairement aux méthodes synchronized
, les instructions synchronisées doivent spécifier l'objet qui fournit le verrouillage intrinsèque.
exemple tiré du tutoriel java:
public void addName(String name) {
synchronized(this) {
lastName = name;
nameCount++;
}
nameList.add(name);
}
déclarations synchronisées sont également utiles pour améliorer la simultanéité avec une synchronisation à grain fin. Vous pouvez trouver un bon exemple sur la même page de tutoriel pour cas d'utilisation ci-dessous.
supposons, par exemple, que la classe MsLunch
comporte deux champs d'instance, c1 et c2, qui ne sont jamais utilisés ensemble. Toutes les mises à jour de ces champs doivent être synchronized
, mais il n'y a aucune raison d'empêcher une mise à jour de c1 d'être entrelacée avec une mise à jour de c2 - et cela réduit la concurrence en créant des blocages inutiles. au lieu d'utiliser des méthodes synchronisées ou d'utiliser la serrure associée, nous créons deux objets uniquement pour fournir des serrures .
et en cas de verrouillage sur une méthode statique, sur quoi prend la serrure ? Quelle est la signification d'un verrou sur la classe ?
dans ce cas, le fil acquiert la serrure intrinsèque de l'objet de la classe associé à la classe. Ainsi l'accès aux champs statiques de la classe est contrôlé par un verrou qui est distincte de la serrure pour toute instance de la classe.
Lorsque vous effectuez une méthode comme synchronisé ( non static
) :
il n'est pas possible d'intercaler deux invocations de la méthode synchronized
sur le même objet. Quand un thread exécute une méthode synchronisée pour un objet, tous les autres threads qui invoquent des méthodes synchronisées pour le même bloc d'objet (suspendre l'exécution) jusqu'à ce que le premier fil soit fait avec l'objet.
si vous faites une méthode comme static synchronized
:
il n'est pas possible d'intercaler deux invocations de la méthode static synchronized
sur différents objets de la même classe. Lorsqu'un thread exécute une méthode static synchronized
pour un objet de la classe a, tous les autres threads qui invoquent les méthodes static synchronized
sur l'un quelconque des objets de la Classe A (SUSPENDRE l'exécution) jusqu'à ce que le premier thread soit fait avec la méthode exécution.
Vous trouver de meilleures solutions pour la synchronisation de cette SE a la question: