Si une méthode synchronisée appels à un autre non-méthode synchronisée, est-il un verrou sur la non-méthode synchronisée
En Java, si une méthode synchronisée contient un appel à une non-synchronisés, peut-être une autre méthode encore accès à la non-méthode synchronisée en même temps? Fondamentalement, ce que je demande, tout est dans la méthode synchronisée avoir un verrou sur elle (y compris les appels à d'autres méthodes synchronisées)? Merci beaucoup
- Tous les commentaires sur ma réponse? Veuillez accepter si cela vous a aidé.
- Je pense que le Gris est la réponse doit être accepté tel qu'il répond exactement à ce qui est demandé.
Vous devez vous connecter pour publier un commentaire.
Oui et non.
Si vous êtes dans un
synchronized
méthode, puis des appels à d'autres méthodes sont égalementsynchronized
par d'autres threads sont bloqués. Toutefois, les appels à la non-synchronisé méthodes par d'autres threads sont pas verrouillé -- n'importe qui peut appeler, à la même période.Aussi, si vous appelez
someSynchronizedMethod()
mais arriver à être à l'intérieur de lasomeNonSynchronizedMethod()
méthode, vous détenez toujours la serrure. Le verrou est activé lorsque vous entrez dans un bloc synchronisé et est désactivé lorsque vous quittez cette méthode. Vous pouvez appeler toutes sortes d'autres méthodes non synchronisées et ils seront encore verrouillé.Mais vous demandons deux choses différentes dans votre question:
Oui. D'autres méthodes peuvent accéder à des non-synchronisé méthodes.
Euh, oui. D'autres appels à synchronisé méthodes sont verrouillés. Mais non synchronisée méthodes ne sont pas verrouillées.
Aussi, n'oubliez pas que si la méthode est
static
le verrou est sur leClass
objet dans leClassLoader
.Si la méthode est une méthode d'instance, puis le verrou est sur l'instance de la classe.
Il y a 2 serrures différentes dans les 2 cas.
Enfin, lorsque vous traitez avec des
synchronized
méthodes d'instance, chaque instance de la classe est ce qui est verrouillé. Cela signifie que deux threads peuvent être dans le mêmesynchronized
méthode en même temps avec différents instances. Mais si les 2 threads tentent d'opérer sursynchronized
méthodes sur le même exemple, on bloquera jusqu'à ce que l'on sort de la méthode.toString()
et d'autres méthodes. Tout dépend de votre objet et les cas d'utilisation.Si thread appels de méthode synchronisée M1 qui appelle à son tour non synchronisées méthode M2, thread B peut encore appeler M2 sans blocage.
Méthode synchronisée acquiert et libère intrinsèque verrou sur l'objet sur lequel elle est appelée. C'est pourquoi il peut bloquer. Non synchronisées méthode ne cherche pas à acquérir un verrou (sauf s'il est fait explicitement dans le code).
Donc, si vous avez besoin pour assurer l'exclusion mutuelle pour M2 ainsi, vous devez vous rendre synchronisé indépendamment du fait que ses interlocuteurs (comme M1) sont synchronisées ou non.
La serrure n'appartient pas à la discussion. La serrure appartient réellement à l'objet(ou de la Classe en cas de niveau de la Classe lock), et un fil acquiert un verrou sur l'Objet(ou de la Classe en cas de niveau de la Classe lock) dans un synchronisé contexte.
Maintenant, il n'y a pas de verrouillage de la propagation dans java comme il est discuté ci-dessus. Voici une petite démo:
public class TestThread {
}
public class ThreadCreator1 implements Runnable {
public class Tâche {
}
public class Task2 {
}
Juste que j'ai utilisé Réentrant de verrouillage ici.
Si le code ci-dessus est exécuté, puis il y aura l'entrelacement entre le 1 et le fil 3, mais si le verrouillage de la partie de Task2 classe est sans commentaire, alors il n'y aura pas d'entrelacement et le fil qui acquérir le verrou de la première, sera complète entièrement en premier, puis il va la libérer, puis l'autre thread peut s'exécuter sur.
La serrure appartient à la fil, pas de la méthode (ou plus précisément, de son stack frame). Il se trouve que si vous avez une méthode synchronisée, vous avez la garantie que le thread sera propriétaire de la serrure avant que le corps de la méthode de démarrage, et sortira par la suite.
Un autre thread peut toujours invoquer la deuxième, non-méthode synchronisée. Une désynchronisation de la méthode peut être appelée par n'importe quel thread à tout moment.