Comprendre java.lang.Thread.State: WAITING (stationnement)

Tout d’abord, une question vraiment stupide, je me demandais juste ce que signifie le «stationnement» en attente. Le fil est-il en attente de stationner ou est-il juste garé et est donc en attente? Et quand ce stationnement se produit, combien de ressources processeur / mémoire sont sockets? Quel est le but de garer un fil?

Deuxièmement, en regardant la méthode de parc dans l’ API de threads Java

Désactive le thread en cours à des fins de planification des threads, sauf si le permis est disponible.

Si le permis est disponible, il est consommé et l’appel est renvoyé immédiatement. sinon, le thread actuel est désactivé à des fins de planification de thread et rest inactif jusqu’à ce que l’une des trois choses se produise …..

L’anglais n’est pas ma langue maternelle, j’ai donc du mal à comprendre cela. J’avais l’intention de «permettre» comme une sorte de «permission de parquer le fil», alors les questions suivantes:

  • quel est le sens de cela, qu’est-ce que “permis”, et qui et comment vérifie ces permis?
  • Qu’est-ce que cela signifie: «si un permis est disponible, il est consommé», devient-il «parqué»?
  • suivre, si le deuxième point est vrai, alors quelle est la différence entre «stationnement» et «est en sumil»? Si j’ai un permis, je peux le garer pour toujours et sinon, je peux le rendre «dormant»?

Merci

Permis signifie une permission de continuer l’exécution. Stationner signifie suspendre l’exécution jusqu’à ce que le permis soit disponible.

Contrairement aux permissions de Semaphore , les permissions de LockSupport sont associées aux threads (c.-à-d. LockSupport est donné à un thread particulier) et ne s’accumulent pas (c.-à-d.

Vous pouvez autoriser un thread en appelant unpark() . Un thread peut suspendre son exécution jusqu’à ce que le permis soit disponible (ou que le thread soit interrompu ou que le délai d’expiration ait expiré, etc.) en appelant park() . Lorsque permis est disponible, le thread parqué le consum et quitte une méthode park() .

Conformément à la documentation relative à l’état des threads java, un thread peut accéder à l’état WAITING pour trois raisons:

  1. Object.wait sans délai d’attente
  2. Thread.join sans délai d’attente
  3. LockSupport.park

Lorsque vous appelez une méthode park sur un thread, il désactive le thread à des fins de planification des threads, sauf si le permis est disponible. Vous pouvez appeler la méthode unpark pour mettre à disposition l’autorisation pour le thread donné, si elle n’était pas déjà disponible.

Ainsi, lorsque votre thread est en mode WAITING par LockSupport.park, il vous indiquera WAITING (stationnement).

Veuillez noter que vous ne pouvez appeler park que sur le fil actuel. Ce mécanisme est très utile pour mettre en œuvre un modèle de conception producteur-consommateur.

De la description de la classe (en haut du javadoc LockSupport ) où il décrit l’autorisation:

Cette classe associe à chaque thread qui l’utilise un permis (au sens de la classe Sémaphore). Un appel au parc reviendra immédiatement si le permis est disponible, consommant [le permis] dans le processus; sinon [l’appel à se garer] peut bloquer. Un appel à unpark rend le permis disponible, s’il n’était pas déjà disponible. (Contrairement aux sémaphores, les permis ne s’accumulent pas. Il y en a au plus un.)

(J’ai développé le [texte] pour le rendre plus facile à lire pour les non-anglophones.)

J’espère que quelqu’un avec une compréhension plus profonde pourra développer cela. Voir la réponse de axtavt.

En conclusion, une citation finale du javadoc:

Ces méthodes sont conçues pour être utilisées en tant qu’outils de création d’utilitaires de synchronisation de niveau supérieur et ne sont pas en elles-mêmes utiles pour la plupart des applications de contrôle de simultanéité.

Si je comprends bien, le “permis” est juste un object qui représente si un fil peut être “non récupéré” ou non. Et ceci est vérifié par le thread lui-même (ou de JRE lorsque vous essayez de parquer un thread). La chose “est consommée”, je comprends que le permis disparaît et que le thread n’est pas désactivé.

Je pense que vous devriez en apprendre un peu plus sur le multithreading. Considérez-le comme un dissortingbuteur d’objects appelés “autoriser”. Vous dites à un fil de se garer, et le fil vérifie le dissortingbuteur, s’il y a un “permis”, le fil le prend et part (sans parc). S’il n’y a pas de “permis” dans le dissortingbuteur, le fil est garé jusqu’à ce qu’un “permis” soit disponible (et vous pouvez mettre un “permis” dans le dissortingbuteur avec le non- unpark .

En ce qui concerne l’utilisation du processeur / de la mémoire, je pense que cela dépend de l’OS, etc.

La partie qui m’a fait revenir sur cette question que je ne pouvais pas contourner en lisant uniquement la documentation était la suivante:

Si le permis est disponible, il est consommé et l’appel retourne immédiatement …

Alors, comment le permis est “disponible”, qui le rend disponible et comment il peut être consommé immédiatement? C’était en quelque sorte sortingvial de découvrir:

 private static void sleep(long howMuch) { try { Thread.sleep(howMuch); } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(Ssortingng[] args) { Thread t = new Thread(() -> { System.out.println("Sleeping..."); sleep(2000); System.out.println("Parking"); LockSupport.park(); System.out.println("After parking"); }); sleep(1000); t.start(); System.out.println("Unparking"); // making the permit available while the thread is running and has not yet // taken this permit, thus "LockSupport.park" will return immediately LockSupport.unpark(t); } 

Le code parle de lui-même, le thread est en cours d’exécution, mais pas encore appelé LockSupport.park , tandis que d’autres threads appellent LockSupport.unpark dessus, ce qui rend le permis disponible. Après cela, nous appelons LockSupport.park et cela revient immédiatement car le permis est disponible.

Une fois que vous y réfléchissez, c’est un peu dangereux, si vous exposez vos threads à du code que vous ne contrôlez pas et que ce code appelle LockSupport.unpark lorsque vous vous park après cela – cela pourrait ne pas fonctionner.