120 votes

Comportement des méthodes statiques dans un environnement multithread en java

class Clstest{

    public static String testStaticMethod(String inFileStr) {

        // section 0

        // section 1

        // do something with inFileStr

        // section 2

        // section 3

        return inFileStr;

    }

}

Supposons qu'il y ait cinq threads qui exécutent chacun un appel à Clstest.testStaticMethod("arg-n") en même temps.

Le fil conducteur 1 appelle Clstest.testStaticMethod("arg-1") .

Lorsque le thread 1 est dans la section 1, le thread 2 appelle Clstest.testStaticMethod("arg-2") .

Alors qu'arrivera-t-il au fil 1 ? Va-t-il passer en état de veille ?

Lorsque le fil 1 en a l'occasion, reprend-il l'exécution à partir de la section 1 où elle a été interrompue ?

Comment ça se passe quand il y en a un Clstest.testStaticMethod et même Clstest.testStaticMethod est partagé entre les cinq fils ?

Est-il possible d'échanger le inFileStr envoyé par plusieurs fils ?

198voto

selig Points 2053

La réponse de Hans Passant est bonne. Mais je me suis dit que j'allais essayer d'expliquer à un niveau un peu plus simple pour tous ceux qui rencontrent ce problème et qui sont novices en Java. Voilà

En Java, la mémoire est divisée en deux catégories : le tas et les piles. Le tas est l'endroit où vivent tous les objets et les piles sont l'endroit où les threads font leur travail. Chaque thread a sa propre pile et ne peut pas accéder aux piles des autres. Chaque thread a également un pointeur dans le code qui indique le bout de code qu'il est en train d'exécuter.

Lorsqu'un thread commence à exécuter une nouvelle méthode, il enregistre les arguments et les variables locales de cette méthode sur sa propre pile. Certaines de ces valeurs peuvent être des pointeurs vers des objets du tas. Si deux threads exécutent la même méthode au même moment, ils auront tous deux leurs pointeurs de code pointant vers cette méthode et auront leurs propres copies des arguments et des variables locales sur leurs piles. Ils n'interféreront l'un avec l'autre que si les éléments de leurs piles pointent vers les mêmes objets du tas. Dans ce cas, toutes sortes de choses peuvent se produire. Mais comme Hans le fait remarquer, les chaînes de caractères sont immuables (ne peuvent pas être modifiées), nous sommes donc en sécurité si c'est le seul objet "partagé".

De nombreux fils peuvent exécuter la même méthode. Ils peuvent ne pas être exécutés en même temps - cela dépend du nombre de cœurs dont dispose votre machine, car la JVM fait correspondre les threads Java aux threads du système d'exploitation, qui sont programmés sur les threads matériels. Vous n'avez donc que peu de contrôle sur la façon dont ces threads s'entrecroisent sans utiliser des outils complexes de gestion de l'exécution. synchronisation mécanismes.

Notez que le sommeil est quelque chose qu'un thread s'inflige à lui-même.

68voto

Hans Passant Points 475940

Va-t-il se mettre en veille ?

Non, l'exécution d'un thread n'affecte pas les autres threads tant qu'ils ne se synchronisent pas intentionnellement entre eux. Si vous avez plus d'un cœur de processeur, ce qui est le cas de toutes les machines récentes, ces threads sont susceptibles de s'exécuter exactement au même moment. Cela devient un peu moins probable lorsque vous démarrez 5 threads car votre machine peut ne pas avoir assez de cœurs. Le système d'exploitation est obligé de choisir entre eux, en leur donnant à chacun un certain temps d'exécution. C'est le travail du planificateur de threads. Un thread ne sera donc pas dans un état de "sommeil", il est simplement en pause et attend que le planificateur de threads lui donne une chance de s'exécuter. Il reprendra là où il a été interrompu par l'ordonnanceur.

Existe-t-il une possibilité d'interchanger les inFileStr envoyés par plusieurs threads ?

Il n'y a pas de telle possibilité, les threads ont leur propre pile, donc tout argument de méthode et variable locale sera unique pour chaque thread. En utilisant un chaîne de caractères garantit en outre que ces threads ne peuvent pas interférer les uns avec les autres puisque les chaînes de caractères sont immuables.

Il n'y a pas de telle garantie si l'argument est une référence à un autre type d'objet mutable. Ou si la méthode elle-même utilise des variables qui sont statiques ou des références à des objets du tas. La synchronisation est nécessaire lorsqu'un thread modifie l'objet et qu'un autre thread le lit. Le site serrure dans le langage C# est la façon la plus simple d'implémenter une telle synchronisation. Le fait que la méthode soit statique ne signifie pas qu'une telle synchronisation n'est jamais nécessaire. Elle est simplement moins probable puisque vous n'avez pas à vous soucier des threads qui accèdent au même objet (partage de l'objet). este ).

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