les termes que j'emploie ne sont pas forcement exacts du point de vue de Java, je laisse les précisions terminologiques a quelqu'un de plus pointu sur le sujet.
Dans la JavaDoc et ailleurs, on parle de "moniteur". J'ai un peu de mal à comprendre ce que c'est précisément (Wikipédia dit que c'est l'ensemble formé par un verrou, par des fonctions utilisant une ressource partagée… mais la définition s'arrête là).
Pour comprendre le concept de moniteur et son intérêt, une bonne idée peut être de lire le papier original de Hoare (Monitors: an operating system structuring concept - 1974).
En Java, les moniteurs sont moins puissants (ils ne gèrent qu'une seule file d'attente), mais le concept reste très proche : le mot clé synchronized
permet de protéger de façon transparente une portion de code contre l’accès concurrent. En réalité, c'est un verrou interne qui est utilisé, a la fois pour gérer l’accès et les primitives wait
et notify
.
Peux-tu juste confirmer, ou infirmer, s'il te plaît, que le moniteur c'est le système interne à la JVM qui gère la notion d'exclusion mutuelle ? C'est-à-dire le système interne qui est caché au programmeur Java tel que moi et qui attribue le verrou d'un synchronized
à tel ou tel thread et donc empêche les autres de le prendre.
Le "moniteur" est le mécanisme général (verrou + file d'attente), pas juste le truc qui attribue le verrou.
D'un autre côté j'ai l'impression que "monitor" est directement synonyme de "verrou", à cause de cette phrase tirée de la JavaDoc : "Wakes up a single thread that is waiting on this object's monitor. "… Pourtant c'est censé être "lock" ou "bolt".
C'est quasiment synonyme, comme vu plus haut.
Heum un verrou peut vraiment gérer quelque chose ? Tu ne veux pas plutôt dire "moniteur" du coup ? (il y aurait donc bien une différence entre moniteur et verrou).
Peu importe le nom, je parlais des verrous internes aux objets de java, pas des objets Lock
(qui s'utilisent autrement).
Le mécanisme de file d'attente est obligatoirement associé a un verrou (directement ou non, je n'en sais rien), c'est ce qui permet de mettre les autres threads en attente du verrou s'il est déjà pris.
Si c'est le moniteur de l'objet appelant wait
/notify
qui gère ça, j'imagine qu'il y a au moins un critère pour choisir cet objet appelant. Peux-tu m'en dire plus si possible ? Est-ce que ce critère ne serait pas, par hasard, le suivant : "utiliser wait/notify
de l'objet passé à synchronized(x)
" ?
Bien sur, et ce n'est pas un hasard, il faut absolument que le verrou (ou moniteur si tu veux) soit le même entre wait et notify.
Aussi, j'aimerais bien savoir pourquoi =/
Chaque verrou est associé a sa propre file d'attente (sinon, bah ce serait le bordel, tu ne sais plus qui tu va notifier).
"Cet autre thread" dont tu parles, c'est un thread contenant notify
?
Oui, pour que notify
puisse passer, il faut que le thread appelant ait la main.
D'ailleurs 4è ou 5è question de ce post ^^' : le verrou peut-il se trouver dans une classe A et dans une classe B, toutes deux héritant de Thread ? Du coup un thread :B pourrait réveiller un thread :A.
Encore une fois, un verrou n'est pas spécialement lié a un thread, mais peut se trouver dans n'importe quel autre objet. Donc oui, n'importe quel thread peut réveiller n'importe quel objet.
Attention de ne pas confondre le code du Thread
et code exécuté par ce thread. D'ailleurs, un thread exécute souvent le code d'un objet Runnable
.