Il semble exister un décalage entre le consensus SO et presque tous les diagrammes d'état des threads Java sur Internet; En particulier, en ce qui concerne la transition d'état du thread fromWAITING
après que notify()
ou notifyAll()
est invoqué ...
Donc, le consensus sur SO est le suivant: un filetage passe de WAITING
à BLOCKED
après avoir appelé notify()
ou notifyAll()
; Le diagramme ci-dessous illustre cette transition en vert.
Pourquoi la plupart des diagrammes d'état sur le Web illustrent-ils la transition de WAITING
à RUNNABLE
, pas BLOCKED
? La représentation en rouge indique une transition incorrecte. est-ce que je manque quelque chose?
Tout diagramme présentant une invocation notify
faisant passer un thread de WAITING à RUNNABLE est incorrect (ou utilise un raccourci non clarifié). Une fois qu'un thread est réveillé d'une notify
(ou même d'un réveil parasite), il doit verrouiller à nouveau le moniteur de l'objet sur lequel il était en attente. C'est l'état BLOCKED
.
Etat de thread pour un thread bloqué en attente d'un verrouillage du moniteur. Un fil dans l’état bloqué attend un verrouillage du moniteur pour entrer un méthode/bloc synchronisé ou entrez à nouveau dans un bloc/méthode synchronisé après appeler
Object.wait
.
Ceci est expliqué dans le javadoc de Object#notify()
:
Le thread réveillé ne pourra pas continuer avant le courant thread abandonne le verrou sur cet objet.
Le thread attend ensuite jusqu'à ce qu'il puisse récupérer la propriété du moniteur et reprend l'exécution.
Un thread est dansEN ATTENTEétat va dansBLOCétat, jusqu'à ce qu'il acquiert moniteur par notification et devienneEXÉCUTABLE.
Il en va de même pourTIMEDWAITING, il passe àBLOCKstate, si monitor est maintenu par un autre thread, même si le temps spécifié est écoulé .(votre diagramme doit être corrigé)
Je me concentre sur le problème récemment.
comme le document Oracle Thread.State indique que nous pouvons utiliser LockSupport.park () pour placer le thread actuel dans l'état "WAITING" ou "TIMED_WAITING".
ainsi, lorsque vous essayez LockSupport.unpark () , le thread spécifié revient à 'RUNNABLE' à partir de 'WAITING'/'TIMED_WAITING'. (Je ne sais pas s'il passera par l'état 'BLOCKED')