106 votes

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

Tout d'abord, une question vraiment stupide, je me demandais juste ce que l'attente "parking" signifiait ? Est-ce que le thread attend d'être garé ou est-ce qu'il vient d'être garé et est donc en état d'attente ? Et quand ce stationnement se produit, combien de ressources cpu/mémoire sont utilisées ? Quel est le but de la mise en attente d'un thread ?

Deuxièmement, en examinant la méthode des parcs en API de threads java

Désactive la discussion en cours à des fins d'ordonnancement des discussions, à moins que l'autorisation ne soit disponible.

Si le permis est disponible, il est consommé et l'appel est renvoyé immédiatement ; dans le cas contraire, le thread en cours est désactivé à des fins de planification des threads et reste en sommeil jusqu'à ce que l'une des trois choses suivantes se produise.....

L'anglais n'étant pas ma langue maternelle, j'ai quelques difficultés à comprendre. J'entendais par "permis" une sorte de "permission de garer le fil de discussion", d'où les questions qui suivent :

  • Qu'est-ce que cela signifie, qu'est-ce qu'un "permis", et qui et comment vérifie ces permis ?
  • Qu'est-ce que cela signifie ? "si le permis est disponible, il est consommé", est-ce qu'il est "parqué" ?
  • ensuite, si le deuxième point est vrai, quelle est la différence entre "se garer" et "rester en sommeil" ? Si j'ai un permis, je peux le garer pour toujours et si je n'en ai pas, je peux le rendre "dormant" ?

Remerciements

41voto

axtavt Points 126632

Le terme "autorisation" désigne l'autorisation de poursuivre l'exécution. Le stationnement signifie la suspension de l'exécution jusqu'à ce que le permis soit disponible.

Contrairement à Semaphore Les permis de l'Union européenne, les permis de l'Union européenne LockSupport sont associés à des fils (c'est-à-dire que le permis est accordé à un fil particulier) et ne s'accumulent pas (c'est-à-dire qu'il ne peut y avoir qu'un seul permis par fil et qu'il disparaît lorsque le fil a consommé le permis).

Vous pouvez autoriser un fil de discussion 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'attente soit expiré, etc. park() . Lorsque le permis est disponible, le thread stationné le consomme et sort d'une session d'apprentissage. park() méthode.

14voto

Badal Points 552

Selon la java Documentation sur l'état des fils Une discussion peut passer à l'état d'attente pour trois raisons :

  1. Object.wait sans délai d'attente
  2. Thread.join sans délai d'attente
  3. [LockSupport.park](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/LockSupport.html#park())

Lorsque vous appelez une méthode park sur un Thread, cela désactive le thread à des fins d'ordonnancement à moins que le permis ne soit disponible. Vous pouvez appeler la méthode unpark pour rendre disponible le permis pour le thread donné, s'il n'était pas déjà disponible.

Ainsi, lorsque votre fil est en mode ATTENTE par LockSupport.park, il vous indiquera comme étant en ATTENTE (parking).

Veuillez noter que vous ne pouvez appeler le parc de stationnement que sur le fil actuel. Il s'agit d'un mécanisme très utile pour mettre en œuvre le modèle de conception producteur-consommateur.

7voto

Eugene Points 6271

La partie qui m'a fait revenir sur cette question, que je n'ai pas pu résoudre en lisant la documentation, est la suivante :

Si le permis est disponible, il est consommé et l'appel revient immédiatement...

Donc quand le permis est "disponible", qui et comment le rend disponible, de sorte qu'il puisse être consommé immédiatement ? Il était en quelque sorte trivial de le découvrir :

public static void main(String[] args) {

    Thread parkingThread = new Thread(() -> {
        System.out.println("Will go to sleep...");
        sleepTwoSeconds();
        System.out.println("Parking...");
        // this call will return immediately since we have called  LockSupport::unpark
        // before this method is getting called, making the permit available
        LockSupport.park();
        System.out.println("After parking...");
    });

    parkingThread.start();

    // hopefully this 1 second is enough for "parkingThread" to start
    // _before_ we call un-park
    sleepOneSecond();
    System.out.println("Un-parking...");
    // making the permit available while the thread is running and has not yet
    // taken this permit, thus "LockSupport.park" will return immediately
    LockSupport.unpark(parkingThread);

}

private static void sleepTwoSeconds() {
    try {
        Thread.sleep(1000 * 2);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

private static void sleepOneSecond() {
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}    

Le code parle de lui-même, le thread est en cours mais pas encore appelé LockSupport.park tandis qu'un autre thread appelle LockSupport.unpark sur celui-ci - rendant ainsi le permis disponible. Ensuite, nous appelons LockSupport.park et qui revient immédiatement puisque le permis est disponible.

Quand on y pense, c'est un peu dangereux, si vous exposez vos threads à un code que vous ne contrôlez pas et que ce code appelle LockSupport.unpark pendant que vous park Après cela, il se peut que cela ne fonctionne pas.

3voto

Charles Goodwin Points 3273

A partir de la description de la classe (en haut de la page d'accueil de la LockSupport javadoc ) où il décrit le permis :

Cette classe associe à chaque thread qui l'utilise une valeur de permis (au sens de la classe Sémaphore). Un appel à la fonction parking renverra immédiatement si le permis est disponible, en consommant [le permis] dans le processus ; sinon [l'appel au stationnement] peut bloquer. Un appel au déblocage rend le permis disponible, s'il ne l'était pas déjà. (Contrairement aux sémaphores, les permis ne s'accumulent pas. Il y en a au plus un).

(J'ai élargi le [texte] pour faciliter la lecture aux non-anglophones).

J'espère que quelqu'un ayant une connaissance plus approfondie de la question pourra m'éclairer sur ce point. Voir la réponse d'axtavt.

Pour finir, une dernière citation de la javadoc :

Ces méthodes sont conçues comme des outils permettant de créer des 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 la concurrence.

1voto

Vic Points 115

Si j'ai bien compris, le "permis" est juste un objet qui représente si une Thread peut être "dégagée" ou non. Et ceci est vérifié par le Thread lui-même (ou par le JRE lorsque vous essayez de stationner un Thread). Pour ce qui est de "est consommé", 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 distributeur d'objets appelés "permis". Vous dites à un Thread de se garer, et le Thread vérifie le distributeur, s'il y a un "permis", le Thread le prend et part (sans se garer). S'il n'y a pas de "permis" dans le distributeur, la Thread reste stationnée jusqu'à ce qu'un "permis" soit disponible (et vous pouvez mettre un "permis" dans le distributeur avec unpark .

Pour ce qui est de l'utilisation du CPU et de la mémoire, je pense que cela dépend du système d'exploitation, etc...

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X