Les tutoriels Java indiquent: "Il n'est pas possible d'entrelacer deux appels de méthodes synchronisées sur le même objet".
Qu'est-ce que cela signifie pour une méthode statique? Puisqu'une méthode statique n'a pas d'objet associé, le mot-clé synchronized sera-t-il verrouillé sur la classe, au lieu de l'objet?
Puisqu'une méthode statique n'a pas d'objet associé, le mot clé synchronized se verrouille-t-il sur la classe au lieu de l'objet?
Oui. :)
Juste pour ajouter un petit détail à la réponse d'Oscar (plutôt succinctement!), La section pertinente de la spécification du langage Java est 8.4.3.6, 'Méthodes synchronisées' :
Une méthode synchronisée acquiert un moniteur (§17.1) avant son exécution. Pour une méthode de classe (statique), le moniteur associé à l'objet Class pour la classe de la méthode est utilisé. Pour une méthode d'instance, le moniteur associé à celui-ci (l'objet pour lequel la méthode a été appelée) est utilisé.
Un point sur lequel vous devez faire attention (plusieurs programmeurs tombent généralement dans ce piège) est qu'il n'y a pas de lien entre les méthodes statiques synchronisées et les méthodes non statiques synchronisées, c'est-à-dire:
class A {
static synchronized f() {...}
synchronized g() {...}
}
Principale:
A a = new A();
Fil 1:
A.f();
Fil 2:
a.g();
f () et g() ne sont pas synchronisés l'un avec l'autre et peuvent donc s'exécuter de manière totalement simultanée.
Sauf si vous implémentez g() comme suit:
g() {
synchronized(getClass()) {
...
}
}
Je trouve ce modèle utile également lorsque je souhaite implémenter une exclusion mutuelle entre différentes instances de l’objet (ce qui est nécessaire lors de l’accès à une ressource externe, par exemple).
Consultez la page de documentation Oracle sur Verrous et synchronisation intrinsèques
Vous vous demandez peut-être ce qui se passe lorsqu'une méthode statique synchronisée est appelée, puisqu'une méthode statique est associée à une classe et non à un objet. Dans ce cas, le thread acquiert le verrou intrinsèque de l'objet Class associé à la classe. Ainsi, l'accès aux champs statiques de la classe est contrôlé par un verrou distinct de celui de toute instance de la classe.
Les exemples ci-dessous donnent plus de clarté entre le verrou de classe et le verrouillage d'objet; l'espoir ci-dessous aidera également les autres
Par exemple, nous avons ci-dessous des méthodes d'acquisition d'une classe et d'autres d'acquisition d'objet:
public class MultiThread {
public static synchronized void staticLock() throws InterruptedException {
for (int i = 0; i < 10; i++) {
Thread.sleep(100);
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
public synchronized void objLock() throws InterruptedException {
for (int i = 0; i < 10; i++) {
Thread.sleep(100);
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
}
Nous pouvons donc maintenant avoir les scénarios suivants:
Lorsque les threads utilisant same object tente d'accéder à la méthode objLock
OUstaticLock
en même temps (c'est-à-dire que les deux threads essaient d'accéder à la même méthode)
Thread-0 0
Thread-0 1
Thread-0 2
Thread-0 3
Thread-0 4
Thread-1 0
Thread-1 1
Thread-1 2
Thread-1 3
Thread-1 4
Lorsque les threads utilisant same Object essaye d'accéder aux méthodes staticLock
et objLock
en même temps (tente d'accéder à différentes méthodes)
Thread-0 0
Thread-1 0
Thread-0 1
Thread-1 1
Thread-0 2
Thread-1 2
Thread-1 3
Thread-0 3
Thread-0 4
Thread-1 4
Lorsque les threads utilisant Object différent tente d'accéder à la méthode staticLock
Thread-0 0
Thread-0 1
Thread-0 2
Thread-0 3
Thread-0 4
Thread-1 0
Thread-1 1
Thread-1 2
Thread-1 3
Thread-1 4
Lorsque les threads utilisant Object différent tente d'accéder à la méthode objLock
Thread-0 0
Thread-1 0
Thread-0 1
Thread-1 1
Thread-0 2
Thread-1 2
Thread-1 3
Thread-0 3
Thread-0 4
Thread-1 4
Une méthode statique a également un objet associé. Il appartient au fichier Class.class de la boîte à outils JDK. Lorsque le fichier .class est chargé dans le ram, le Class.class en crée une instance appelée modèle.
Exemple: - lorsque vous essayez de créer un objet à partir de la classe de clients existante, comme
Customer c = new Customer();
Le Customer.class charge dans la RAM. À ce moment, Class.class dans le kit JDK crée un objet appelé Objet modèle et charge ce Customer.class dans cet objet modèle. Les membres statiques de ce Client deviennent des attributs et des méthodes dans cet objet modèle.
Donc, une méthode statique ou un attribut a aussi un objet
Pour ceux qui ne sont pas familiers avec la méthode synchronisée statique verrouillée sur un objet de classe, par exemple. pour la classe string, String.class tandis que la méthode instance synchronisée verrouille l'instance actuelle de Object, indiquée par le mot clé «this» en Java. Comme ces deux objets sont différents, ils ont un verrou différent. Ainsi, lorsqu'un thread exécute une méthode synchronisée statique, un autre thread en Java n'a pas besoin d'attendre le retour de ce thread. méthode synchronisée statique.