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

Langage Java Discussion :

Java.Lang.Integer : Incrémentation


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2007
    Messages : 128
    Par défaut Java.Lang.Integer : Incrémentation
    Bonjour ou bonsoir,

    Un objet de la classe Java.Lang.Integer est immuable.
    Disons que l'on a un objet "i" qui est une instance de cette classe avec comme paramètre passer au constructeur l'entier 0.
    Il est permis de faire : i++.
    Est-il possible qu'en itérant cette opération x fois, le pointeur de cet objet change pour une autre instance qui contient donc l'entier x ? Si oui, pourquoi ?

    Je vous pose cette question car j'ai fais une découverte bizarre :
    J'ai une classe(appelé test contenant le main) qui a notamment un static objet Integer(qui contient le chiffre 0) : Static Integer i = new Integer(0);
    J'ai une classe modInt qui implémente Runnable.
    Code du constructeur : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    modInt(int i) {
    	this.thread = new Thread(this, "modInt n° " + Integer.toString(i));
    	this.ID = i;
    }

    Code du run() : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    for (int i = 1; i <= 200000; i++) {
    	synchronized(test.i){
    		test.i++;
    	}
    }
    System.out.println("Dernière valeur enregistré :" + test.i);
    Dans mon main, je crée 3 objet modInt et je les démarre avec (new modInt(1)).thread.start(), (new modInt(2)).thread.start() et (new modInt(3)).thread.start().
    En toute logique, à la fin de l'execution des 3 objets, je devrais obtenir :
    Dernière valeur enregistré : x(>0)
    Dernière valeur enregistré : y(>200000)
    Dernière valeur enregistré : 600000
    Or je n'obtient pas 600 000. Cela veut dire qu'il y a un problème d'accès sur l'Integer i. Or j'y met un verrou dessus.
    Donc soit le pointeur de i a changé et donc les modInt ne travaillent plus sur le même i ou alors je comprends pas..
    Pourriez vous m'éclairer ?

    Merci

  2. #2
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 582
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    Citation Envoyé par zizoufoot Voir le message
    Un objet de la classe Java.Lang.Integer est immuable.
    C'est java.lang.Integer, et oui, en effet, ils sont immutables. Leur état interne ne peut pas changer.

    Citation Envoyé par zizoufoot Voir le message
    Disons que l'on a un objet "i" qui est une instance de cette classe avec comme paramètre passer au constructeur l'entier 0.
    Il est permis de faire : i++.
    Est-il possible qu'en itérant cette opération x fois, le pointeur de cet objet change pour une autre instance qui contient donc l'entier x ?
    Non seulement c'est possible, mais c'est absolument certain. À la première itération il sera remplacé par un autre objet (son pointeur changera, donc,) de même qu'à l'itération suivante, et ainsi de suite.

    Citation Envoyé par zizoufoot Voir le message
    Si oui, pourquoi ?
    Soyons logiques :
    - comme tu l'as dit, ces objets sont immutables. Leur état interne ne peut pas changer.
    - Or, en effet, et assez malheureusement, on peut faire i++ dessus. En faisant cela, la variable i devient un Integer de la valeur suivante.
    - Donc avant, c'est un Integer de valeur 0, ensuite un Integer de valeur 1.
    - Or un Integer ne peut pas changer de valeur.
    - Donc si l'Integer avant n'a pas la même valeur que l'Integer après, c'est que ce ne sont pas les mêmes.
    Logique.

    À chaque itération, l'objet Integer est remplacé par un autre, de la valeur suivante.

    Ce qui explique donc que tes tentatives de synchronisation échouent.
    Synchronise plutôt sur un Object quelconque que tu crées au début juste pour ça.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre très actif
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2007
    Messages : 128
    Par défaut
    Merci pour tes précisions.

    Ne t'inquiète pas, ce code là avait pour but de montrer ce que j'expliquais, je n'utilise jamais ce genre de procédure sinon ^^

    Hier, je cherchais des informations sur la mnémonique "++", que je n'ai pas trouvé pour appuyer ce que je pensais. D'ailleurs si tu sais où je peux trouver ce genre d'infos, je suis preneur !
    Je trouve ça quand même intriguant..
    Si je suis la logique, si je déclare : Integer i = new Integer(0);
    Et que je fais (i++)++; En toute logique, ça devrait marcher puisque i++ retourne un nouvel Integer.. Mais ça ne marche pas ^^'

    Mmmmmm

  4. #4
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 582
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    Citation Envoyé par zizoufoot Voir le message
    Hier, je cherchais des informations sur la mnémonique "++", que je n'ai pas trouvé pour appuyer ce que je pensais. D'ailleurs si tu sais où je peux trouver ce genre d'infos, je suis preneur !
    Pour quelque chose de ce niveau, il va falloir voir la Java Language Specification. J'y ai trouvé la définition de l'opérateur ++ en Java.

    Citation Envoyé par zizoufoot Voir le message
    Je trouve ça quand même intriguant..
    Si je suis la logique, si je déclare : Integer i = new Integer(0);
    Et que je fais (i++)++; En toute logique, ça devrait marcher puisque i++ retourne un nouvel Integer..
    Aaah, non. En toute logique, au contraire, ça devrait pas marcher.
    Puisque i++ renvoie un Integer, une valeur donc, on ne peut pas l'incrémenter. On peut incrémenter des variables, pas des valeurs.

    L'idée d'incrémenter quelque chose, c'est de changer sa valeur. Une variable, c'est fait pour ça, très bien. Mais une valeur renvoyée, on peut pas changer sa valeur, elle est une valeur. Ce serait comme dire qu'on veut incrémenter 2. On ne peut pas changer 2, 2 c'est 2.

    Bon, par contre, on pouvait pas deviner a priori que i++ renvoie une valeur Integer et pas la variable i... Mais c'est indiqué dans le paragraphe dont j'ai donné le lien.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Membre très actif
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    128
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juin 2007
    Messages : 128
    Par défaut
    Merci pour le lien, j'ai cherché comme un dingue xD J'avais des résultats pour solaris, c'était énervant

    Je vais lire de ce pas tout ça

    Encore merci

    Edit : Ok, tout est clair maintenant.
    L'opération d'incrémentation effectue un unboxing sur l'objet java.lang.Integer, puis un +1 classique à la valeur, puis un boxing de la somme. Cette opération de boxing recrée un nouvel objet java.lang.Integer qui n'a donc plus le même pointeur que l'objet java.lang.Integer d'avant.
    Chaque thread se partagent donc une variable sans verrou et là c'est la foire.

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

Discussions similaires

  1. java.lang.Integer pas finalisable ?
    Par Khaled.Noordin dans le forum Langage
    Réponses: 10
    Dernier message: 28/04/2011, 16h58
  2. Réponses: 2
    Dernier message: 24/02/2009, 13h24
  3. java.lang.Integer avec Axis1.4
    Par clement42 dans le forum Services Web
    Réponses: 3
    Dernier message: 20/07/2007, 14h49
  4. [JSTL] Attempt to coerce a value of type "java.lang.Integer" to Boolean
    Par jamalmoundir dans le forum Taglibs
    Réponses: 3
    Dernier message: 26/06/2007, 10h40
  5. Réponses: 1
    Dernier message: 01/05/2007, 13h48

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