11
votes

Java multithreading et variables globales

J'ai une classe Java qui démarre 2 threads distincts. Le premier thread démarre bien et toutes les variables sont correctes.

Lorsque je démarre le second thread, les variables globales à partir du fil d'une autre modification des valeurs définies dans le fil 2. P>

J'ai essayé d'ajouter des blocs synchronisés Lorsque les variables globales sont mises à jour, mais cela n'a pas fonctionné. P>

Y a-t-il un moyen de résoudre ce problème? Je veux que chaque threffe démarre et utilise ses propres valeurs sans interférence dans d'autres valeurs de thread. P>

EDIT: P>

Snippet de ma classe de thread: p>

  public abstract class ConsumerIF implements Runnable {

      public static Element root = null;
      public static String name = null;
      public static String type = null;
      public static String location = null;

      public final synchronized void reconfigure() throws FatalDistributionException {


            Document doc = builder.build(new StringReader(xmlCollector));
            root = doc.getRootElement();
            Element nameElement = root.getChild("name");
            Element typeElement = root.getChild("type");
            Element locationElement = root.getChild("location");
            Element scheduleElement = root.getChild("schedule");

            if (nameElement != null && typeElement != null && locationElement != null){
                name = nameElement.getTextTrim();
                type = typeElement.getTextTrim();
                location = locationElement.getTextTrim();
            }

      }
  }


3 commentaires

je. e. Supprimer tout statique que vous avez pu utiliser


Coller votre code serait utile


Les variables statiques sont partagées entre toutes les instances de votre «consommateur»


5 Réponses :


6
votes

La synchronisation contrôle simplement l'accès des threads à l'état partagé.

Si vous voulez des états distincts par thread, vous devez soit déclarer des instances différentes de ces informations (par exemple les classes) par fil. par exemple. Instanciez simplement un nouvel objet dans chaque fichier thread 'S. exécuté () méthode ou effectuez une copie de la structure en question (par exemple, une copie profonde d'une collection)

Une alternative consiste à enquêter ThreadLocal , dans lequel chaque thread aura une copie différente d'une ressource désignée.


0 commentaires

0
votes

Si je comprends correctement, vous devez probablement regarder le modificateur final modificateur: xxx

ceci garantit que s ne peut pas être modifié, Ainsi, vos discussions ne pourront pas changer sa valeur.

Assurez-vous également que vos threads ne tentent pas de modifier les valeurs qu'ils ne devaient pas, copiez-les à la place.


4 commentaires

Il n'est pas mentionné qu'il ne veut pas modifier du tout, il ne veut tout simplement pas que un autre fil modifie.


Je lis toujours le poteau et je ne peux pas décider de ce qu'il fait et veut. "Je veux que chaque fil démarre et utilise ses propres valeurs sans interférence dans d'autres valeurs de thread." Son comme final et / ou copie pour moi. Mais il se peut que ses variables soient statiques et ne devraient pas.


Je suis une fille :) lol mais oui regardez le snippet ci-dessus - il est modifié, je ne veux tout simplement pas que d'autres threads modifient mes valeurs de fil actuelles


Désolé, je faisais référence à l'OP (anglais n'est pas ma langue maternelle), mais dans ce cas s'il vous plaît jeter ma réponse.



16
votes

Les variables statiques sont partagées entre tous les threads, c'est ce qui les rend statiques. Si vous souhaitez utiliser différentes valeurs, utilisez des lecteurs de discothèque ou (bien mieux), utilisez différents objets avec des variables non statiques dans les threads différents. Sans autre code, il est difficile de dire plus.


1 commentaires

Simple mais définissant. :)



2
votes

Si vous ne voulez pas votre variable partagée, alors ne pas utiliser de global em> variable (probablement moyenne statique code> en Java). Créer un nouveau champ avec un nouvel objet initialisé lorsque votre thread commence. Exemple:

public class UniqueThreadIdGenerator {
      private static final AtomicInteger uniqueId = new AtomicInteger(0);

      // Value obtained from uniqueNum.get() will be thread-local even though uniqueNum is static
      private static final ThreadLocal <Integer> uniqueNum = new ThreadLocal <Integer> () {
           @Override protected Integer initialValue() {
                return uniqueId.getAndIncrement();
           }
      };

      public static int getCurrentThreadId() {
           return uniqueNum.get();
      }
 }


3 commentaires

Merci! Je vais supprimer les variables statiques? Et jeter un oeil à ThreadLocal?


@ LULU88 En regardant votre code, il suffit de supprimer statique devrait aider.


Votre premier exemple doit imprimer "Bonjour à partir d'un thread avec objet:" + myThreadVariable Pour illustrer que chaque thread a une instance unique non partagée de MyObject. Votre deuxième exemple n'a pas besoin de diplocal. Atomicinteger effectue tout le travail pour vous et assurera des valeurs entières uniques.



0
votes

Si vous souhaitez utiliser des variables statiques, vous devez utiliser des blocs synchronisés sur l'objet de la classe à l'intérieur de vos méthodes synchronisées. xxx

}

Assurez-vous que toutes vos variables statiques sont accessibles à partir d'une méthode / bloc synchronisée sur l'objet plutôt que sur une variable d'instance ou cette instance. La méthode synchronisée que vous avez utilisée est applicable sur Cette instance signifie l'objet actuel avec lequel vous appelez la méthode et que les variables statiques sont partagées par tous les objets.


0 commentaires