Je sais que lorsque vous souhaitez verrouiller la méthode pour être exécutée par un seul thread, vous le déclarez avec Qu'en est-il des classes, comment fournir une serrure sur une classe entière d'objets lorsqu'un fil
exécute du code sur une instance de cette classe? P>
En d'autres termes, lorsqu'un thread exécute une méthode sur un objet, aucun autre fil ne doit être
autorisé à exécuter la même méthode même sur un exemple différent de la même classe. p> synchronisé code> mot-clé. p>
8 Réponses :
Il n'y a pas de mécanisme intégré pour cela. Créez votre propre attribut de verrouillage statique et assurez-vous de le verrouiller et de le déverrouillez-le dans chaque méthode. N'oubliez pas d'exceptions - assurez-vous de le déverrouiller dans les sections "enfin". P>
Si vous utilisez des méthodes synchronisées statiques, elles sont verrouillées via la serrure de la classe. Vous pouvez également déclarer un objet statique dans la classe et verrouiller que dans une méthode, je crois via quelque chose comme:
Cela devrait fonctionner:
public class MyClass {
void synchronizedMethod() {
synchronized (MyClass.class) {
// synchronized on static level
}
}
}
Étant donné que les méthodes synchronisées statiques se synchronisent sur l'objet de la classe, pourquoi considérez-vous de le faire une mauvaise utilisation?
Est-ce vrai? Dans ce cas, si les concepteurs Java le font comme ça, alors ce n'est probablement aucune solution. Je pensais que le moyen le plus propre était d'avoir un moniteur statique dédié / mutex, et que l'utilisation d'un objet est quelque peu un piratage - même si je choisirais personnellement cette option moi-même. Mettez la Missuse dans des citations maintenant :)
Vous vous synchronisez sur un objet spécifique, soit un objet de verrouillage statique désigné, soit l'objet de la classe (qui se produit lorsque des méthodes statiques sont déclarées synchronisées):
class State {
private int value;
public synchronized void mutate(){ value++; }
}
class Z {
private final State state;
public Z(State state){
this.state = state;
}
public void oneAtATime(){
state.mutate();
}
}
// Usage:
State s1 = new State(), s2 = new State();
Z foo = new Z(s1);
Z bar = new Z(s1);
Z frob = new Z(s2);
Z quux = new Z(s2);
Cette (dernier) chemin est presque certainement le meilleur que je dirais. Il le rend transparent ce qui est censé se produire avec des sous-classes de votre classe et avec de multiples instances de votre programme, ainsi que quoi faire attention lorsque des méthodes statiques sont nécessaires.
Synchroniser sur le champ statique de votre classe ou la classe elle-même:
Les deux threads doivent utiliser cette construction
public void someMethod() {
synchronized(ClassThatShouldBeProtected.class) {
someSynchronizedCode();
}
}
http://www.janeg.ca/scjp/threads/synchronization.html p>
parle de plusieurs façons de l'atteindre. En général, les verrous sont prohibitifs et entravent les avantages du filetage. Donc, le code critique doit donc être minimisé autant que possible. P>
Voulez-vous qu'un verrouillage du levier de classe accède aux variables statiques de la classe ou est-ce de protéger l'accès à une ressource externe commune la classe? Dans ce cas, vous devriez prolier avoir un verrou séparé tout en y accédant. p>
Pouvez-vous expliquer pourquoi vous devez faire cela? J'ai un sentiment que vous attaquez peut-être le mauvais problème. Besoin de synchroniser des appels de méthode sur Des instances complètement différentes de votre classe i> comme le vrai problème est ailleurs.