web-dev-qa-db-fra.com

Comportement de méthode statique dans un environnement multithread dans java

Il y a une simple question stupide qui me dérange et me fait penser à plusieurs arguments. Je veux lever tous les doutes sur les questions ci-dessous.

class Clstest{

    public static String testStaticMethod(String inFileStr) {

        // section 0

        // section 1

        // do something with inFileStr

        // section 2

        // section 3

        return inFileStr;

    }

}

Supposons que cinq threads exécutent chacun un appel à Clstest.testStaticMethod("arg-n") en même temps.

Le fil 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 à Thread 1? Est-ce qu'il va dormir?

Lorsque le fil 1 aura la chance de reprendre l’exécution à partir de la section 1 où il a été mis en pause?

Comment cela se passe-t-il quand il y a un Clstest.testStaticMethod Et que le même Clstest.testStaticMethod Est partagé entre les cinq threads?

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

109
namalfernandolk

La réponse de Hans Passant est bonne. Mais j’ai pensé que j’essaierais d’expliquer un peu plus simplement ceux qui découvrent cette nouveauté de Java. Voici..

La mémoire dans Java est divisée en deux types - le tas et les piles. Le tas est le lieu de vie de tous les objets et les piles sont le lieu où les threads travaillent. 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 pointe vers le morceau de code qu'ils exécutent actuellement.

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 sur des objets du tas. Si deux threads exécutent la même méthode en même temps, leurs pointeurs de code pointent vers cette méthode et ont leurs propres copies d'arguments et de variables locales sur leurs piles. Ils n'interféreront les uns avec les autres que si les objets stockés sur leur pile pointent vers les mêmes objets sur le tas. Dans ce cas, toutes sortes de choses pourraient arriver. Mais comme le fait remarquer Hans, les chaînes de caractères sont immuables (elles ne peuvent pas être modifiées). Nous sommes donc en sécurité s'il s'agit du seul objet "partagé".

Tant de threads peuvent exécuter la même méthode. Ils ne fonctionnent peut-être pas en même temps. Cela dépend du nombre de cœurs de votre machine que la machine virtuelle Java mappe Java threads vers les threads du système contrôle sur la façon dont ces threads s'entrelacent sans utiliser de mécanismes synchronisation complexes.

Notez que dormir est quelque chose qu'un fil se fait à lui-même.

186
selig

Est-ce qu'il va dormir?

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 plusieurs cœurs de processeur, comme 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 risque de ne pas avoir assez de cœurs. Le système d'exploitation est obligé de choisir entre eux, ce qui lui laisse un peu de temps pour s'exécuter. Le travail du planificateur de threads. Un thread ne sera alors pas dans un état de "veille", il est simplement suspendu et attend que le planificateur de thread lui donne une chance de s'exécuter. Il reprendra là où il a été interrompu par le planificateur.

Est-il possible d'échanger l'inFileStr envoyé par plusieurs threads?

Il n'y a pas une telle possibilité, les threads ont leur propre pile, ainsi tout argument de méthode et variable locale sera unique pour chaque thread. L'utilisation de chaîne garantit en outre que ces threads ne peuvent pas interférer les uns avec les autres puisque les chaînes 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 statiques ou des références à des objets sur le tas. La synchronisation est requise lorsqu'un thread modifie l'objet et qu'un autre thread le lit. Le mot clé lock dans le langage C # est le moyen le plus adapté pour mettre en œuvre la synchronisation requise. Le fait que la méthode soit statique ne signifie pas qu'une telle synchronisation n'est jamais requise. Juste moins probable puisque vous n'avez pas à vous soucier des threads accédant au même objet (partage this).

64
Hans Passant