Essayer de visualiser et de comprendre synchronisation.
Code A
public class MyClass1 {
private static final Object lock = new Object();
public MyClass1() {
//unsync
synchronized(lock) {
//sync
}
//unsync
}
}
Code B
public class MyClass2 {
private final Object lock = new Object();
public MyClass2() {
//unsync
synchronized(lock) {
//sync
}
//unsync
}
}
Remarque
Le code ci-dessus montre les constructeurs, mais vous pouvez aussi expliquer en quoi le comportement est différent dans une méthode statique et une méthode non statique. Serait-il également avantageux d'utiliser un verrou statique lorsque le bloc synchronisé modifie une variable membre statique?
J'ai déjà regardé les réponses dans cette question , mais ce n'est pas assez clair quels sont les différents scénarios d'utilisation.
La différence est simple: si l'objet verrouillé se trouve dans un champ static
, alors toutes les instances de MyClass*
partager ce verrou (c'est-à-dire qu'il n'y aura pas deux objets capable de verrouiller cet objet en même temps).
Si le champ n'est pas statique, chaque instance aura son propre verrou, donc seuls les appels de la méthode sur le même objet se verrouillent mutuellement.
Lorsque vous utilisez un objet de verrouillage statique:
o1.foo()
o1.foo()
, devra attendre que le thread 1 se termineo2.foo()
, aussi devra attendre que le thread 1 (et probablement 2) se termineLorsque vous utilisez un objet de verrouillage non statique:
o1.foo()
o1.foo()
, devra attendre que le thread 1 se termineo2.foo()
, il peut simplement continuer, sans se soucier des threads 1 et 2Lequel de ceux dont vous aurez besoin dépend du type de données que vous essayez de protéger avec votre bloc synchronisé.
En règle générale, vous voulez que le verrou-objet ait la même static
- ness que la valeur opérée. Donc, si vous manipulez des valeurs non statiques niquement, vous aurez besoin d'un objet de verrouillage non statique. Si vous manipulez des valeurs statiques niquement, vous aurez besoin d'un objet de verrouillage statique.
Lorsque vous manipulez des valeurs statiques et non statiques, cela devient compliqué. La manière facile serait d'utiliser simplement un objet de verrouillage statique, mais cela pourrait augmenter la taille du bloc synchronisé plus qu'absolument nécessaire et pourrait nécessiter plus de conflits de verrouillage que souhaité. Dans ces cas, vous pourriez avoir besoin d'une combinaison d'objets de verrouillage statiques et non statiques.
Dans votre cas particulier, vous utilisez le verrou dans le constructeur, qui ne sera exécuté qu'une seule fois par instance, donc un objet de verrouillage non statique n'a aucun sens ici.