salut,
je voudrais gérer et contrôler mes variables globales d'une classe mère dans une autre classe interne qui utilise des threads.
autrement dit comment conserver les valeurs de chaque variable globale appelé dans une classe thready.
et merci
salut,
je voudrais gérer et contrôler mes variables globales d'une classe mère dans une autre classe interne qui utilise des threads.
autrement dit comment conserver les valeurs de chaque variable globale appelé dans une classe thready.
et merci
Salut,
Il n'y a pas de notion de variables globales en Java. On peut déclarer des variables comme public static, ce qui permet à des variables d'être d'une part accessibles par toutes autres classes (le public) et à ne pas être attachées à une instance particulière. Si la variable doit être modifiée et lue par différents threads, on la déclarera volatile en plus.
Par exemple, si on a une variable déclarée comme ça :
On pourra y accèder comme ça :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 public class UneClasse { public static volatile String variable = "truc"; }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 public class UneAutreClasse { public void uneMethode() { System.out.println( UneClasse.variable ); } }
Si la classe est interne elle pourra toujours accèder aux variables membres, même si elles ne sont ni static ni public.
Exemple avec classes anonymes :
Exemple avec classes internes :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 public class DemoVar { private volatile int variable; public DemoVar() { new Thread() { @Override public void run() { while(true) { System.out.println(variable); try { sleep(500); } catch (InterruptedException e) { break; } } } }.start(); new Thread() { @Override public void run() { while(true) { variable++; System.out.println("variable modifiée"); try { sleep(1500); } catch (InterruptedException e) { break; } } } }.start(); } public static void main(String[] args) { new DemoVar(); } }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 public class DemoVar { private volatile int variable; public DemoVar() { new Thread(new ReadRunnable()).start(); new Thread(new WriteRunnable()).start(); } private class ReadRunnable implements Runnable { @Override public void run() { while(true) { System.out.println(variable); try { Thread.sleep(500); } catch (InterruptedException e) { break; } } } } private class WriteRunnable implements Runnable { @Override public void run() { while(true) { variable++; System.out.println("variable modifiée"); try { Thread.sleep(1500); } catch (InterruptedException e) { break; } } } } public static void main(String[] args) { new DemoVar(); } }
L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
Nouveau sur le forum ? Consultez Les Règles du Club.
Sinon, tu peux aussi aller faire un tour dans le package java.util.concurrent pour regarder les objets qui s'appellent AtomicBoolean, AtomicInteger, AtomicLong... bref, plein d'objets pour manipuler toutes sortes d'objets dans un contextes concurrentiel en limitant les risques de modification concurrentes et de lock.
Je ne suis pas mort, j'ai du travail !
Salut,
Je suis tout a fait d'accord avec ces solutions que vous m'avez proposé , mais mon intérêt de déclarer des variables qu'on peut les utiliser dans une classe thready c'est en fait comme la notion des variables locales dans une fonction càd je veux lancer plusieurs thread qui ont les mêmes variables mais leurs valeurs sont différentes selon notre traitement dans autre classe.
"thready" n'est pas une notion de programmation, donc dur de savoir précisément ce que tu veux.
Les champs des classes étant spécifiques à chaque instance, il suffit de filer des instances différentes de tes classes à chaque thread et tu n'aura pas de soucis entre les thread.
Si ce que tu cherche à faire c'est à stocker une variable "globale" mais dont l'état dépend du thread qui la lit, regarde du coté de la classe ThreadLocal.
Exactement ce que vous avez dit, on veut utiliser les variables globales dont leur état dépend du thread lancer et en cours d'éxecution.
voila un exemple expliquant mon but :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 public class projet { public int variable_global = 0; projet() { Applica ap = new Applica(); ap = new Thread(); ap.start(); ap = new Thread( new String("salut") ); ap.start(); ap = new Thread(); ap.start(); } Public void main() { new projet(); } }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 public class Applica extends Thread { public String msg; public Applica() { // TODO Auto-generated constructor stub this.variable_global= 3; } public Applica(String msg) { this.variable_global= 10; this.msg=msg; } public void run() { while(true) { System.out.println(" afficher le message "+msg); System.out.println(" la valeur de variable"+variable_global); } } //fin run() }
mon projet lance plusieurs threads en paralelle, mais je veux la valeur de variable de chaque thread reste au meme thread.une autre solution c'est de declarer le variable variable_global au classse thread et l'exploiter en classe projet mais il me donne erreur car ce variable est seulement propre au classe thread.
Même si ThreadLocal peut t'apporter une solution, je ne te le recommande pas. Commence par regarder à filer une instance de ton set de variable à chaque Thread. Si "Projet" a besoin de variables, mais qu'elles doivent être différenciée par thread, ça veux surement dire que ce dont tu as besoin, c'est d'une instance de Projet par thread et non pas d'une instance globale. On utilise une instance de type ThreadLocal quand on n'a pas le choix, par exemple quand on n'a aucun controle sur la création de Threads comme dans une serveur d'application, et que l'on n'a pas accès aux structure chargée habituellement de stocker les informations spéciques prévues par le conteneur. Avec les systèmes d'injection actuels, c'est devenu assez rare.
Ce n'est pas du tout ce dont parlais @Tchize_ : il parlait d'une variable qui a une valeur différente pour chaque thread qui la manipule (on utilise une variable de type ThreadLocal pour gérer ça).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 public class UneClasse { private void ThreadLocal<Integer> var = new ThreadLocal<>(); public void set(int i) { var.set(i); } public int get() { return var.get(); } }Ce programme affiche en continu des lignes comme ça :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 public class Demo { public static void main(String[] args) { UneClasse uneClasse = new UneClasse(); new Thread() { public void run() { uneClasse.set( 42 ); while( true ) { System.out.println("Variable thread 1 : " + uneClasse.get() ); } } }.start(); new Thread() { public void run() { uneClasse.set( 139 ); while( true ) { System.out.println("Variable thread 2 : " + uneClasse.get() ); } } }.start(); } }
C'est la même instance de UneClasse, la même variable, mais chaque thread à sa propre valeur.Variable thread 1 : 42 Variable thread 2 : 139
Dans ton cas, tu as une variable qui est membre de la classe Projet et tu veux y accèder dans une autre classe, Applica. La variable étant membre de Projet elle n'est accessible depuis une instance de Applica que par l'intermédiaire d'une instance de classe Projet.
Le code que tu montres semble par contre contradictoire à ce que tu expliques, qui n'est pas très clair d'un autre côté. Dans le code que tu montres, il semble que tu aies besoin simplement d'une variable statique (une seule valeur en commun à toutes les classes) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 public class UneClasse { public static volatile int variable; }
Ici chaque thread a sa propre instance de UneClasse, mais la variable est static, donc unique (n'est pas attachée à une instance en particulier), en quelque sorte partagée entre toutes les instances. Donc les 2 threads vont continuellement incrémenter la même valeur et le programme va afficher des lignes comme ça :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 public class Demo { public static void main(String[] args) { new Thread() { public void run() { UneClasse uneClasse = new UneClasse(); while( true ) { uneClasse.variable ++; System.out.println("Variable thread 1 : " + uneClasse.variable ); } } }.start(); new Thread() { public void run() { UneClasse uneClasse = new UneClasse(); while( true ) { * * * * * * * * * * * * * * uneClasse.variable ++;* System.out.println("Variable thread 2 : " + uneClasse.variable ); } } }.start(); } }
etc...Variable thread 1 : 1 Variable thread 2 : 2 Variable thread 1 : 3 Variable thread 2 : 4 Variable thread 1 : 6 Variable thread 2 : 6 Variable thread 1 : 7 Variable thread 1 : 9 Variable thread 2 : 9
L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
Nouveau sur le forum ? Consultez Les Règles du Club.
on peut dire que le threadlocal soit une solution mais c'est juste si on utilise ces variables locales dans son propre classe thread.
tant qu'on voudrais lancer nos instances de thread par la même façon déjà montré et dans la classe Projet on aura des appels à notre variable_globale
donc à ce moment là on peut pas faire appeler aux variables du classe thread Appli si on déclare variable_globale comme variable locale.
notre méthode Run() va être exécuter a chaque appel d'un instance de thread mais notre traitement de notre variable_globale soit au classe Projet.
Je vais faire mon chieur sur un autre point : quand on met en place des threads, les classes qui doivent travailler en thread doivent implémenter Runnable et pas étendre Thread.
Quand on étend une classe, on sous-entend qu'on modifie/améliore son fonctionnement. Accessoirement, ça permet de pouvoir créer sa propre hiérarchie de classes mères.
Bref, ça coute pas cher et c'est plus propre de faire ça :
Dernier point, ton code a plein d'erreur de compilation, et tu fais ça
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 Applica ap = new Applica(); Thread thread = new Thread(ap); thread.start();
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 projet() { Applica ap = new Applica(); ap = new Thread(); // déjà, ça ne compile pas ça, et ensuite, tu as perdu ta référence vers ton objet Applica ap.start(); }
Ensuite, si ton but est que chaque INSTANCE de ton objet Applica lancé par Thread soit modifié uniquement par le thread courant, il faut faire un truc dans le genre ;
Ici, tu auras lancé deux threads différents qui agiront chacun sur leur instance de Applica (dans laquelle tu peux utiliser des déclaration de variables simples, mais sans le mot clé static qui n'aurait pas de sens : tu veux que la valeur soit propre à l'instance et pas à la classe)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 Applica ap1 = new Applica(<insérer ici la valeur désirée>); // ca implique d'avoir un constructeur dans lequel tu passes le paramètre Thread t1 = new Thread(ap1); t1.start(); Applica ap2 = new Applica(<insérer ici la valeur désirée>); Thread t2 = new Thread(ap2); t2.start();
Si tu veux lancer plusieurs threads avec la même instance de Applica, tu fais comme ça :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 Applica ap1 = new Applica(<insérer ici la valeur désirée>); // ca implique d'avoir un constructeur dans lequel tu passes le paramètre Thread t1 = new Thread(ap1); t1.start(); Thread t2 = new Thread(ap1); t2.start();
Je ne suis pas mort, j'ai du travail !
Je voudrais pas faire la modification de notre variable_globale mais garder leur contenu pour chaque appel d'un thread
et la façon de lancer notre thread c 'est comme vous m'avez montré:
mais notre application va faire des traitements qui dépendent de notre valeur de variable_globale comme suit:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 Applica ap1 = new Applica(<insérer ici la valeur désirée>); // ca implique d'avoir un constructeur dans lequel tu passes le paramètre Thread t1 = new Thread(ap1); t1.start(); Applica ap2 = new Applica(<insérer ici la valeur désirée>); Thread t2 = new Thread(ap2); t2.start();
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 public class Projet { public Projet(){} while(true) { if(variable_globale=="5") // traitement1 if(variable_globale=="10") // traitement2 } }
ces traitements seront exécutés tant que nos threads sont en cours d’exécution.sachant qu'on pourrait arrêter nos thread selon des conditions données dans la méthode Run() de classse Appli.
Donc si je résume :
- Tu auras plusieurs instances de Applica qui vont tourner chaque dans leur coin au chaud dans le thread sans aucun lien entre elles
- Chaque instance possèdera une valeur (que tu appelles variable globale) qui lui sera envoyée à l'initialiation
- Cette valeur pour chaque instance de Applica évoluera indépendamment des autres valeurs des autres instances de Applica
- Tu veux tester toutes ces valeurs dans ta classe Projet et déclencher des traitements en fonction des valeurs
Si c'est ça, je pense que tu as avant tout un problème de design : chaque variable à l'intérieur d'une instance Applica ne vit que dans cette instance et n'est accessible que PAR cette instance de la classe.
Du coup posons la question autrement : tu parles d'un traitement selon l'état de la variable d'une instance de Applica... Du coup, ne serait-ce pas à Applica de gérer ça?
Autre piste : si tu cherches à déclencher des actions spécifiques lors de modification de la valeur de la variable, tu devrais jeter un oeil sur le concept Observer/Observable : http://gscheibel.developpez.com/articles/observer/
Je ne suis pas mort, j'ai du travail !
c'est exactement ce que je cherche et j'aimerais le faire dans mon programme, faire lancer des instances des classe en thread et gérer les valeurs des variables de chaque thread appelé bien sur les variables qui sont a propre au classe thread(Appli).
et pour la solution observateur/observé, je croix pas qu'il marche car cette solution concerne des variables communes entre les threads appelés mais changeable par le temps, mais dans mon cas l'initialisation de chaque variable se fait au constructeur de la classe thread et après des traitements vont être exécutés selon les variables de classe Thred (Appli).
Avec Observer, tu inspecte/observe une instance d'une classe, donc ses variables internes aussi (si tu y as accès), pas une classe.
Donc ça devrait fonctionner !
Du coup, soit chaque instance peut déclencher ses actions selon les variations de sa variable interne, soit les actions en fonction de la valeur de chaque instance doit être gérée dans un contrôleur. Auquel cas il existe pas beaucoup de solutions pour vérifier les changements d'état :
- boucler sur la liste d'Applica pour vérifier chaque valeur (couteux en CPU pour pas grand chose)
- mettre en place un Observer/Observable
Je ne suis pas mort, j'ai du travail !
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager