J'ai lu dans un manuel Java ce qui suit concernant le multi-threading.
Pour qu'un thread appelle wait () ou notify (), le thread doit être le propriétaire du verrou pour cet objet. Quand le thread attend, il libère temporairement le verrou pour d'autres threads à utiliser, mais il aura besoin à nouveau pour continuer l'exécution.
Je ne sais pas ce que signifie la clause
Lorsque le thread attend, il libère temporairement le verrou pour d'autres fils à utiliser
Je ne comprends pas de quoi parle cette clause. Cela signifie-t-il que lorsque la méthode wait () est appelée, elle libère en fait le verrou avant le retour de wait () (c'est-à-dire que cela se produit sans que l'appelant le sache)? Ou fait-il simplement allusion à wait (timeout) qui libère le verrou lorsque le délai est écoulé? Si c'est le premier, pourquoi libérerait-il le verrou avant notify () ? Cela semble être une déclaration vague et mal expliquée.
3 Réponses :
Lorsqu'un thread appelle wait, le thread libère le verrou immédiatement puis passe en dormance jusqu'à ce que le délai expire, le cas échéant, ou jusqu'à ce qu'il reçoive une notification, ce qui se produit lorsqu'un autre thread acquiert le même verrou que le thread en attente. up et les appels notifient dessus (le planificateur doit également choisir le thread en attente parmi tous les autres threads en attente; appeler notify ne notifie pas un thread donné, il dit au planificateur de choisir un thread dans l'ensemble d'attente d'un verrou donné pour notifier) .
Une fois que le thread est réveillé par une notification, il doit réacquérir le verrou afin de quitter la méthode wait, car le thread est toujours à l'intérieur d'une méthode ou d'un bloc synchronisé. C'est ce que signifie le guillemet quand il dit que le thread aura besoin du verrou pour reprendre l'exécution.
Pour qu'un thread appelle wait () ou notify (), le thread doit être le propriétaire du verrou pour cet objet.
Sinon, une erreur d'exécution se produit et le reste du code n'est pas exécuté.
Lorsque le thread attend, il libère temporairement le verrou pour d'autres threads à utiliser
Pour plus de détails, appeler wait () fait ce qui suit:
Ensuite, certains threads appellent notify () ou notifyAll () , ce qui fait qu'un ou tous les threads enregistrés comme en attente sur ce moniteur sont déplacés de l'attente réglé sur l'ensemble prêt, en attendant qu'un processeur libre s'exécute.
mais il en aura à nouveau besoin pour continuer l'exécution.
Cela signifie que l'exécution du thread se poursuit avec l'exécution de l'instruction synchronized pour retrouver le verrou. Une fois le verrou acquis, la méthode wait () retourne. wait (timeout) diffère en ce que, sauf pour notify () ou notifyAll () , il peut également revenir à l'expiration du délai.
En résumé, vous devez comprendre comment un thread bascule entre les 4 états suivants:
Lorsqu'un thread appelle wait () , il libère temporairement le moniteur (verrou) de l'objet jusqu'à ce qu'il reçoive une notification d'un autre thread. De cette façon, un thread peut volontairement donner le contrôle (qu'il a, en premier lieu) du moniteur de l'objet à un autre thread. Jetez un coup d'œil à la documentation :
L'appel de
wait ()ne revient pas tant qu'un autre thread n'a pas a émis une notification indiquant qu'un événement spécial peut s'être produit - mais pas nécessairement l'événement que ce thread attend (donc toujours invoquezwait ()dans une boucle qui teste la condition en cours attendu)....
Quand
wait ()est appelé, le thread libère le verrou et suspend exécution. À un moment ultérieur, un autre thread acquerra le même verrouiller et invoquer Object.notifyAll, en informant tous les threads en attente ce verrou que quelque chose d'important s'est produit.
Avant d'appeler
wait (), le thread possède le verrou, après avoir appeléwait (), le thread abandonne le verrou et attend la notification, au retour dewait (), il possède à nouveau le verrou. Appelez toujourswait ()avec une bouclewhile (), cela aide à vérifier la condition à la fois avant et après l'obtention du verrou. Il suffit d'écrire une démo en utilisantwait ()etnotify ()/notifyAll ()pour voir comment cela fonctionne, vous ne pouvez pas le comprendre sans impliquez-le par vous-même.L'appel de
wait ()(ou ses surcharges de délai d'expiration) doit libérer le verrou sinon comment un autreThreadpourrait-il obtenir le verrou dans l'ordre appeleznotifier ()/notifyAll ()? Notez également qu'unThreadobtient un verrou d'unObjecten utilisantsynchronized (someObj) {...}.