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

Android Discussion :

AsyncTask et variables membres


Sujet :

Android

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Avril 2005
    Messages
    156
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 156
    Par défaut AsyncTask et variables membres
    Bonjour a tous,

    Je me demandais un truc a propos des AsyncTask : est-il thread-safe d'avoir une classe heritant d'AsyncTask et qui contient des variables membres utilisees dans doInBackground et onPostExecute ?

    Par exemple :

    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
    public static class RequestTask extends AsyncTask<String, Void, Document> {
     
        private Object mObject;
     
        @Override
        protected Document doInBackground(String... params) {		
            Document result = null;
            // ...
            mObject = ...;
            return result;
        }
     
        @Override
        protected void onPostExecute(Document result) {
            if (mObject != null) {
                // ...
            }		
        }
     
    }
    Ca fonctionne, mais je ne pense pas que cela soit tres propre, qu'en pensez-vous ?
    Merci !

  2. #2
    Membre très actif Avatar de _Xavier_
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    311
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2009
    Messages : 311
    Par défaut
    C'est une classe "static", une instance pouvant être partagée par plusieurs threads pouvant ) leur tour modifié tes variables : ton asyncTask n'est pas thread safe.

  3. #3
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par _Xavier_ Voir le message
    C'est une classe "static", une instance pouvant être partagée par plusieurs threads pouvant ) leur tour modifié tes variables : ton asyncTask n'est pas thread safe.
    Non : pour une classe, le static indique seulement que la classe n'es pas lié implicitement avec une instance de la classe conteneur... C'est tout !
    Cela n'a aucun impact sur le coté thread-safe...



    Je ne connais pas bien la plateforme Android, mais AsyncTask semblent être un genre de SwingWorker amélioré...


    Ton attribut private mObject n'est accédé que par deux méthodes : doInBackground() et onPostExecute(). Et d'après la documentation on est sûr que ces deux accès ne seront pas manipulé en parallèle (onPostExecute() est exécuté à la fin de doInBackground()).

    Donc il n'y a aucun problème à ce niveau là.


    Le seul problème qu'il peut y avoir, et qui est assez difficile à mettre en évidence, c'est que la JVM peut "optimisez" les accès aux champs pour un thread et ne pas s'apercevoir qu'il a été modifié depuis un autre thread.

    Pour éviter cela, il faut déclarer l'attribut en volatile.


    a++

  4. #4
    Membre confirmé
    Inscrit en
    Avril 2005
    Messages
    156
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 156
    Par défaut
    Merci adiGuba, c'est le genre de reponse claire et precise que j'apprecie beaucoup !

  5. #5
    Membre très actif Avatar de _Xavier_
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    311
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2009
    Messages : 311
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Salut,


    Non : pour une classe, le static indique seulement que la classe n'es pas lié implicitement avec une instance de la classe conteneur... C'est tout !
    Cela n'a aucun impact sur le coté thread-safe...
    Je n'ai pas dit qu'une classe static n'est pas thread-safe. C'est quand ses variables peuvent être modifiées dans différents threads qu'elle le devient. (Ok c'est aussi valable pour un objet non static)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
       @Override
        protected Document doInBackground(String... params) {		
            Document result = null;
            // ...
            mObject = ...;
            return result;
        }
     
        @Override
        protected void onPostExecute(Document result) {
            if (mObject != null) {
                // ...
            }		
        }
    Il n'est pas possible qu'on se trouve dans une situation où dans un thread on fait doInbackground() (en modifiant mObject) et dans un autre on fait (onPostExecute() (où l'on teste mObject) ?

    Le seul problème qu'il peut y avoir, et qui est assez difficile à mettre en évidence, c'est que la JVM peut "optimisez" les accès aux champs pour un thread et ne pas s'apercevoir qu'il a été modifié depuis un autre thread.
    On peut être dans cette situation et être thread-safe ?

  6. #6
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par _Xavier_ Voir le message
    Je n'ai pas dit qu'une classe static n'est pas thread-safe. C'est quand ses variables peuvent être modifiées dans différents threads qu'elle le devient. (Ok c'est aussi valable pour un objet non static)
    Donc le mot clef static n'a rien à voir là dedans

    Citation Envoyé par _Xavier_ Voir le message
    Il n'est pas possible qu'on se trouve dans une situation où dans un thread on fait doInbackground() (en modifiant mObject) et dans un autre on fait (onPostExecute() (où l'on teste mObject) ?
    Ces deux méthodes étant protected on ne peut pas les appeler directement. Et sauf erreur on ne peut exécuter la tâche qu'une seule fois


    Citation Envoyé par _Xavier_ Voir le message
    On peut être dans cette situation et être thread-safe ?
    Si tu n'utilises pas volatile tu n'est pas sûr du comportement. Donc tu pourrais ne pas voir la modification effectué dans l'UI.

    Franchement dans ce cas précis c'est peu courant, mais il s'agit de chose qui peuvent très bien arriver...

    a++

  7. #7
    Membre très actif Avatar de _Xavier_
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    311
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2009
    Messages : 311
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Donc le mot clef static n'a rien à voir là dedans


    Ces deux méthodes étant protected on ne peut pas les appeler directement. Et sauf erreur on ne peut exécuter la tâche qu'une seule fois
    Le theard A fait doInBackground : il modifie maObject
    Le thread B fait onPostExecute : il lit maObject

    Le fait d'avoir des méthodes protected éloigne le risque d'incohérence ?

    Tu fais quoi de la variable partagée ?

    Citation Envoyé par adiGuba Voir le message
    Si tu n'utilises pas volatile tu n'est pas sûr du comportement. Donc tu pourrais ne pas voir la modification effectué dans l'UI.
    Dans ce cas c'est pas thread-safe, d'où ma première intervention que l'auteur du thread ne semble pas apprécier.

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

Discussions similaires

  1. [POO] Classe abstraite PHP5 et variables membres
    Par Invité dans le forum Langage
    Réponses: 3
    Dernier message: 07/06/2006, 01h27
  2. Réponses: 3
    Dernier message: 03/05/2006, 15h08
  3. comment récupérer une variable membre?
    Par marute dans le forum MFC
    Réponses: 4
    Dernier message: 13/04/2006, 16h11
  4. Réponses: 5
    Dernier message: 19/09/2005, 20h58
  5. Réponses: 6
    Dernier message: 06/10/2004, 12h59

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