Je veux comprendre comment le verrouillage est effectué sur des méthodes statiques en Java.
Disons que j'ai la classe suivante: p> C'est ma compréhension que lorsque j'appelle que quand j'appelle Ma question est la suivante: comment les deux appels sont-ils synchronisés les uns sur les autres?
Appelle une méthode statique acquiert également une serrure sur toutes les instanciations, ou l'inverse autour (qui semble plus raisonnable)? P> Ma question n'est pas exactement comment f.get () code>, le thread acquiert la verrouillage de l'objet
f code> et lorsque je fais
foo.inc () code> Le fil acquiert le verrouillage Sur la classe
foo code>. p>
statique synchronisée statique code> fonctionne, mais comment les méthodes statiques et non statiques sont synchronisées les unes avec les autres.
I.e., je ne veux pas que deux threads appellent simultanément les deux
f.get () code> et
foo.inc () code>, mais ces méthodes acquièrent des serrures différentes. Ma question est de savoir comment est-ce évitaable et est-il empêché dans le code ci-dessus. P> p>
6 Réponses :
Synchronisation de Je ne veux pas que deux threads appellent simultanément à la fois f.get () et foo.inc (), mais ces méthodes acquièrent des serrures différentes. Ma question est la suivante: comment est-ce évitaable et qu'elle est empêchée dans le code ci-dessus p>
blockQuote>
Vous devez partager un verrou pour pouvoir arbitrer l'accès aux deux statique code> Les verrous sont connectés à la définition code> code> et est donc partagée entre toutes les instances de ce classe em>. p>.
Aucun statique code> s'applique uniquement à l'instance actuelle de la classe (la serrure se trouve sur la classe instance em>, par exemple,
ceci code> ). Dans votre exemple, vous avez deux serrures différentes sans interrelation. p>
f.get code> et
foo.inc () code>. Vous pouvez le faire soit en partageant la même serrure statique ou en verrouillage de la même instance. p>
Ni, l'appel synchronisé non statique n'accepte pas de verrouillage sur la classe elle-même. (Et le bloc synchronisé statique ne verrouille aucun objet instancié de cette classe.) P>
En d'autres termes, les appels Vous pouvez utiliser un motif différent (singleton) ou faire toutes les méthodes statiques. P> f.get () code> (verrous
f code>) et
foo.inc () code> (verrouille la classe
FOO code>) peut fonctionner simultanément. Ils ne sont pas "synchronisés". p>
Pas sûr de comprendre votre commentaire - la méthode statique synchronisée acquièce une verrouillage de la classe code> code>, mais pas sur un objet créé avec celui-ci ( foo a = nouveau foo (); code> -
foo.inc () code> verrouille la chose renvoyée par
a.getclass () code>, mais pas
a code>). Ou je me trompe?
foo.inc () code> ou
nouveau foo (). Inc () code> verrouille les uns aux autres, ce qui verra également contre
foo.dec () code> s'il a été déclaré
statique code>.
Oui, parce qu'ils verrouillent tous les deux la classe. Et aucun de ces acteurs d'un objet instancié de cette classe comme le A code> dans mon commentaire précédent ou votre nouvel objet FOO sans nom. Je ne vois pas ce qui ne va pas dans le libellé de ma réponse.
Une méthode statique synchronisée est effectivement équivalente à: en d'autres termes, il se verrouille sur l'objet code> de classe code> associé à la classe déclarant la méthode. p> de section 8.4.3.6 de Les JLS : P> 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 de classe pour la classe de la méthode est utilisé. Pour une méthode d'instance, le moniteur associé à cela (l'objet pour lequel la méthode a été appelé) est utilisé. P>
blockQuote> p>
Ces deux appels ne se synchronisent pas par rapport à l'autre.
C'est comme vous l'avez dit, un appelant de f.get () code> acquiert la serrure de
f code> objet et appelant de
foo.inc () code> acquiert
FOO.CLASS CODE> L'objet est un. Donc, les règles de synchronisation sont les mêmes que si elles sont au lieu d'appel statique, vous appelez une méthode synchronisée d'instance avec un autre objet. P>
statique et instance méthodes synchronisées code> ne sont pas liées les unes aux autres, vous devez donc appliquer une synchronisation supplémentaire entre eux, comme celle-ci:
class Foo {
private static AtomicInteger bar = new AtomicInteger(0);
public static void inc() { bar.getAndIncrement(); }
public int get() { return bar.get(); }
}
Si vous lisez http://download.oracle.com/javase /Tutorial/essential/concurrency/LockSync.html . P>
Il vous dira: P>
Vous pourriez vous demander ce qui se passe quand un La méthode statique synchronisée est invoquée, puisque une méthode statique est associée avec une classe, pas un objet. Dans ce cas, le fil acquiert le Verrouillage intrinsèque pour l'objet de classe associé à la classe. Ainsi accès Les champs statiques de la classe sont contrôlés par un verrou qui est distinct de la Verrouiller pour toute instance de la classe. P> blockQuote>
qui vous dit tout ce que vous avez besoin de savoir. p>