Question à propos de Java synchronisé
La documentation de Java dit que "il n'est pas possible pour deux invocations de méthodes synchronisées sur le même objet à interleave". Ce que j'ai besoin de savoir, c'est si synchronisée permettra également d'éviter une méthode synchronisée dans les deux instances de la même classe de l'entrelacement.
E. g. Travailleur de la classe a méthode process(). Nous avons plusieurs cas de Travailleur exécute dans leur propre fils. Nous voulons éviter que plus d'une instance en cours d'exécution de la méthode process() simultanément. Va synchronisé faire cela?
Grâce.
- Merci à tous ceux qui ont répondu!
- Ont-ils répondu à votre question? Pourriez-vous accepter une réponse alors que nous savons qu'il est fait?
Vous devez vous connecter pour publier un commentaire.
Pas;
synchronized
n'empêche plusieurs threads simultanément l'exécution de la méthode dans le même instance. Si vous avez n cas, il pourrait être n fils, chaque exécution de la méthode dans l'une des instances.Si vous avez besoin d'assurer qu'un seul thread peut exécuter la méthode dans tous les cas, vous devriez faire de la méthode
static
, ou faire de la méthode non-synchronized
et plutôt utiliser unsynchronized
bloc à l'intérieur de la méthode de se verrouiller sur unprivate static
champ.Edit: Notez que la synchronisation sur un
private
variable d'instance est préférable d'avoir unsynchronized
méthode ou de synchroniser surthis
, et que le verrouillage sur unprivate static
variable d'instance est préférable d'avoir unstatic synchronized
méthode ou une méthode d'instance qui se synchronise surthis.getClass()
. La raison en est quethis
etthis.getClass()
sont des références à des objets qui sont accessibles tout au long du programme, donc n'importe qui peut se synchroniser sur ces objets, et ainsi de bloc de threads que voulez appeler votre méthode.Edit: voir Aussi @Cowan de commentaire ci - dessous: résumé: si vous voulez vraiment de se verrouiller sur la classe, vous pouvez utiliser
synchronized (Worker.class)
plutôt quesynchronized (this.getClass())
, en fonction de l'effet que vous voulez dans le cas de sous-classement.this.getClass()
pour une autre raison - il ne fonctionnera pas dans la présence de l'héritage! Si le Travailleur de la classe a deux classes enfant, FooWorker et BarWorker, puis invocations .processus() prendra différentes serrures lorsqu'elle est appelée sur une instance de FooWorker vs une instance de BarWorker. D'accord que leprivate static
variable est une meilleure idée, mais si vous NE voulez synchroniser sur la classe, être explicite:synchronized(Worker.class)
Non, de la synchronisation de ne pas le faire. Plus précisément synchronisés sur le niveau de l'instance ne sera pas le faire. Au lieu de cela, vous aurez à se synchroniser sur le niveau de la classe.
Par exemple au lieu d'avoir:
Vous aurez le code:
this.getClass()
parce que cet objet est également disponible pour le reste du code, ce qui signifie que si une autre partie du code décide de se synchroniser sur lesTheClass.class
, les appels àmethod()
sera bloqué (sauf si vous voulez vraiment un comportement). Mieux synchroniser sur uneprivate static
variable.Pas moins que la méthode est
static
. Unsynchronized
non méthode statique prend un verrou sur l'objet (instance) sur laquelle elle est invoquée, non pas sur la classe.Synchronisé méthode statique prend un verrou sur la classe, ce qui pourrait l'aider, mais c'est souvent pas très pratique.
Ce que vous pourriez faire est d'avoir un membre statique de l'objet dans votre classe, et de faire un bloc synchronisé sur que (de classe mondiale) de l'objet dans votre
process
méthode.Non, la méthode synchronisée des verrous sur l'objet spécifique (le "il"), donc 2 instances de la même classe de verrouillage sur des objets différents.
Si vous souhaitez synchroniser à travers toutes les instances d'une classe, vous devez utiliser un bloc synchronisé DANS la méthode, le verrouillage statique objet final.
Je l'ai un peu en désaccord avec Aasmund -- bien d'accord un peu en même temps:
Si vous utilisez une construction comme ceci:
puis Aasmund est juste, ce qui n'empêchera pas plusieurs instances de la
Worker
de la classe à exécuterprocess()
en parallèle.Toutefois, vous pouvez utiliser le
synchronized
mot encore pour se synchroniser sur un membre statique pour éviter que cela se produise:Un seul thread peut placer un verrou sur un objet à la fois.
Une méthode synchronisée tenter de placer un verrou sur l'instance. Un autre thread peut également placer un verrou sur une autre instance de la même classe. Un autre thread ne peut pas entrer dans une autre méthode synchronisée de la même instance. c'est à dire qu'elle n'est pas la méthode qui est verrouillé.
Cependant un thread peut entrer dans une non-méthode synchronisée, tandis qu'un autre thread détient un verrou sur l'objet. Seulement synchronisé méthodes sont protégées.
Une méthode synchronisée statique obtient un verrou sur la Classe plutôt que de l'objet. Cependant, le suit les mêmes règles que non méthode statique, sauf avec un autre objet.
Remarque: Il n'est pas un "exemple" pour la méthode statique, même si vous pouvez écrire du code qui s'affiche à l'utilisation d'une instance. par exemple,
instance.staticMethod()
Si vous faites de la méthode
process
statique, il n'autorise qu'une seule invocation de la méthode en même temps.Si ce n'est pas possible, avoir une variable statique, dire
Integer lock
;Et l'utilisation
synchronized (lock)
à l'intérieur de votre méthodeprocess
.c'est