IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Concurrence et multi-thread Java Discussion :

Thread et visibilité des variables


Sujet :

Concurrence et multi-thread Java

  1. #1
    Membre confirmé
    Inscrit en
    Juillet 2009
    Messages
    93
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 93
    Par défaut Thread et visibilité des variables
    Bonsoir
    D'avance merci pour votre lecture
    Je travaille en ce moment sur la conception d'une interface graphique.
    J'ai obtenu un comportement que je ne m'explique pas. Afin de l'illustrer voici un exemple
    mon main
    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
    import java.io.IOException;
    import javax.swing.SwingUtilities;
     
    public class Exemple {
    	private final static exemple_frame mes_frames[] = new exemple_frame[1];
    	public static void main (String [] args)throws IOException {
    		final int k = 0;
    		SwingUtilities.invokeLater(new Runnable(){
    			public void run(){
    				mes_frames[k] = new exemple_frame("Exemple 0");
    				mes_frames[k].setVisible(true);//On la rend visible
    				if (!mes_frames[k].equals(null)) {
    					System.out.println("je suis connu dans mon thread createur");
    				} else {
    					System.out.println("je ne suis pas connu dans mon thread createur");
    				}
    			}
    		});
    		/*if (!mes_frames[k].equals(null)) {
    			System.out.println("je suis connu dans le main");
    		} else {
    			System.out.println("je ne suis pas connu dans le main");
    		}*/
    		SwingUtilities.invokeLater(new Runnable(){
    			public void run(){
    				if (!mes_frames[k].equals(null)) {
    					System.out.println("je suis connu dans un nouveau thread");
    				} else {
    					System.out.println("je ne suis pas connu dans un nouveau thread");
    				}
    			}
    		});
    	}
    }
    ma definition de JFrame
    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
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
     
    import javax.swing.*;
     
     
    public class exemple_frame extends JFrame {
    	public exemple_frame(String title){
    		super();
     
    		build(title);//On initialise notre fenêtre
    	}
     
    	private void build(String title){
    		setTitle(title); //On donne un titre à l'application
    		setSize(400,240); //On donne une taille à notre fenêtre 
    		setLocationRelativeTo(null); //On centre la fenêtre sur l'écran
    		setResizable(true); //On autorise la redimensionnement de la fenêtre
    		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //On dit à l'application de se fermer lors du clic sur la croix
    	}
     
    }
    Un code pas très sorcier qui crée une JFrame et regarde ou elle est connu
    Dans les 2 threads lancé aucun soucis.
    J'ai le résultat attendu la variable mes_frames étant déclaré avant et déclaré static, final les deux threads l'adresse sans problème

    Là ou je ne comprends plus c'est lorsque j'essaye de faire le test dans le main(en virant les commentaires), je ramasse un
    Exception in thread "main" java.lang.NullPointerException
    at Exemple.main(Exemple.java:21)

    Merde un pointeur null mais pourtant j'ai déclaré la variable avant et initialisé aussi, non là je ne pige pas

    Merci de votre aide

  2. #2
    Membre émérite Avatar de worm83
    Homme Profil pro
    Architecte logiciel
    Inscrit en
    Février 2010
    Messages
    459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte logiciel
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2010
    Messages : 459
    Par défaut
    Bonjour,

    Ce comportement est normal car tu n'a instancie aucun objet exemple dans ta methode main....,du coups aucune des ses variables ont été instancie. Si au debut de ton main tu fait un new Exemple.mesFrame ton programme devrait fonctionner.

    Ceci st du au fait que la methode main() est la première entre d'un programme java, qui plus est static et possède donc le comportement de toute les classes static...


    cordialement



    Edit : je crois que j'ai répondu complètement à cote.... je suis fatigué je vais allé me coucher.

  3. #3
    Membre confirmé
    Inscrit en
    Juillet 2009
    Messages
    93
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 93
    Par défaut
    Bonsoir,
    Tout d'abord merci de ta contribution

    Je ne pense pas que tu es répondu à côté, je pense qu'il y a des éléments de réponses mais j'avoue ne toujours pas comprendre le comportement

    Au vue de ce que tu dis et du résultat
    Je présume que mon tableau est instancié quand je fais le new mais que les valeurs de mon tableau ne le sont pas.

    Seulement je ne comprends pas la suite pourquoi la valeur serait connu dans un autre thread différent et pas dans le main

    non vraiment ce code me fout H.S

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Février 2003
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 38
    Par défaut
    Bonsoir

    Donc effectivement il me semble pas que la première réponse soit à coté de la plaque.

    Donc effectivement, ton main déclare le tableau, mais pas les objets (l'example_frame) qu'il contiendra. La fenêtre n'est construire que dans ta première thread anonyme.

    Donc tu as 3 thread dans ce programme, celle qui exécute le main, celle qui construit la fenêtre et la 2e thread anonyme.

    Le problème se situe au niveau de l'ordonnancement des thread. Lorsque tu fais ton test qui pose problème, la première thread anonyme n'a pas encore été lancée donc l'objet qui ira dans le tableau n'a donc pas encore été créé. D'ou le null pointer.

    Par contre, pour la 2e thread anonyme vu que le code de la première a déjà été exécuté, il n'y a pas de souci.

    Pour pallier à ce problème, il faut que ta main frame attende que l'objet a bien été construit (Je ne suis pas spécialiste en la matière donc il y a peut etre une bien meilleur solution que ce que je vais proposer). Tu peux pour gérer cette attente utiliser un sémaphore. En gros, ton main va attendre que le sémaphore soit lui permette d'avancer pour faire le test (avec un appel a aquire() ). Juste après la création de la fenetre, la première thread anonyme appel un release() sur le semaphore pour pouvoir débloquer le code du main.

    Par contre, fais quand mm attention à l'ordre entre les deux thread, ici avec le invoke later, la 2e s'éxécute bien après la première, mais si les thread étaient plus complexe, avec des entrée sorties ou quoi que ce soit qui puisse redonner la main, l'ordre d'exécution pourrait s'inverser. Donc il faut bien veiller à ce que tes objets soient bien construit et dans des états valide lorsqu'il passe d'une thread à l'autre (avec des synchronize, des locks et des semaphore (et autres outils que je peux ne pas connaitre...) )

    Bon code

  5. #5
    Membre confirmé
    Inscrit en
    Juillet 2009
    Messages
    93
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 93
    Par défaut
    Merci beaucoup, pour cette explication nette et précise
    J'utilisais des threads car je lisais dans des tutos que les interfaces graphiques se gèrent comme ça, mais je n'avais pas réfléchis au conséquence.
    Merci pour tout ces précisions, je vais revoir les threads en java


    EDIt je fais des bétises

  6. #6
    Membre émérite Avatar de worm83
    Homme Profil pro
    Architecte logiciel
    Inscrit en
    Février 2010
    Messages
    459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte logiciel
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2010
    Messages : 459
    Par défaut
    Re,

    Apres un tit sommeil ca va mieux.
    Alors deja tu peut résoudre ton problème de null pointeur exception comme cela :

    if (!(mes_frames[k]==null)) {
    System.out.println("je suis connu dans le main");
    } else {
    System.out.println("je ne suis pas connu dans le main");
    }


    Le problème viens du fait que ton objet n'est pas instancie et tu fait appel a une de ses methodes..... du coup ca ne marche pas.
    Quand on compare a une valeur null, on utilise pas object.equals(null), mais oject == null car on utilse le pointeur de l'objet et non pas sa référence.

    peace

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. visibilité des variables d'un constructeur
    Par med_anis_dk dans le forum Langage
    Réponses: 4
    Dernier message: 06/05/2007, 21h07
  2. Réponses: 6
    Dernier message: 06/04/2007, 14h10
  3. Visibilité des variables
    Par Akhan dans le forum MATLAB
    Réponses: 1
    Dernier message: 22/01/2007, 23h22
  4. problème de visibilité des variables dans un include
    Par d1g-2-d1g dans le forum Langage
    Réponses: 6
    Dernier message: 28/11/2005, 09h35
  5. [EasyPHP] problème de visibilité des variable dans les includes
    Par d1g-2-d1g dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 4
    Dernier message: 23/10/2005, 01h55

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo