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

Java Discussion :

Questions sur URLClassLoader et Class


Sujet :

Java

  1. #1
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 326
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste Programmeur

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 326
    Billets dans le blog
    12
    Par défaut Questions sur URLClassLoader et Class
    Bonjour,

    Je souhaiterais vous poser quelques questions sur les classes URLClassLoader et Class.


    1. Lorsqu'on instancie une classe URLClassLoader, le jar (ou les jars) qui est récupéré, est placé en forme de fichier sur la machine ou bien directement stocké en RAM ?


    2. Pourriez-vous me dire quels sont les impacts les plus négatifs lors de l'utilisation des classes URLClassLoader et Class (par étape) :
    • a. Instancier une classe URLClassLoader (récupérer un jar situé sur la machine locale, réseau local ou internet).
    • b. Chargement d'une classe (création d'un objet Class avec la méthode loadClass de URLClassLoader)
    • c. Créer une nouvelle instance (avec la méthode newInstance() de la classe Class).



    3. Considérant que le jar est récupéré à partir du réseau ou internet, pensez-vous que ce soit un bon moyen d'obscurcir son script dans certains cas particuliers ? (ex: je ne veux pas que les personnes qui décompilent le code sache quelle est la méthode de calcul pour augmenter le niveau d'un personnage dans un jeu).
    L'objectif n'est pas de sécuriser, mais de retarder la découverte de cette méthode de calcul.


    4. Y a-t-il une différence entre Class.forName("Toto") et objetURLClassLoader.loadClass("Toto") ?


    Merci
    N'hésitez pas à consulter la FAQ Java, lire les cours et tutoriels Java, et à poser vos questions sur les forums d'entraide Java

    Ma page Developpez | Mon profil Linkedin | Vous souhaitez me contacter ? Contacter Gokan EKINCI

  2. #2
    Membre très actif

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    608
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 608
    Par défaut
    1. Lorsqu'on instancie une classe URLClassLoader, le jar (ou les jars) qui est récupéré, est placé en forme de fichier sur la machine ou bien directement stocké en RAM ?

    C'est assez difficile à dire, désormais.
    Depuis la version 1.6 Java sait compiler en mémoire vive un source et utiliser sa classe directement comme si elle faisait partie du programme original.
    Néanmoins, je pense qu'il y a toujours une représentation sur le disque de la classe.
    J'en suis quasi certain pour URLClassLoader, parce que les antivirus alarment souvent sur des jars tiers au chargement des applications. Je ne vois pas comment ils pourraient agir si les classes n'existaient pas sur le disque.


    2. Pourriez-vous me dire quels sont les impacts les plus négatifs lors de l'utilisation des classes URLClassLoader et Class (par étape) :
    • a. Instancier une classe URLClassLoader (récupérer un jar situé sur la machine locale, réseau local ou internet).
    • b. Chargement d'une classe (création d'un objet Class avec la méthode loadClass de URLClassLoader)
    • c. Créer une nouvelle instance (avec la méthode newInstance() de la classe Class).


    C'est à peu près pareil tout ça.
    Au final, il s'agit juste de sélectionner le DefaultClassLoader ou un ClassLoader externe avant d'y trouver sa classe.
    Tous finissent par faire un findClass et loadClass donc à part la récupération sur un emplacement externe de ton jar par URLClassLoader, si c'est ton choix, où tu perdras un peu en performances, je ne vois pas de differences.


    3. Considérant que le jar est récupéré à partir du réseau ou internet, pensez-vous que ce soit un bon moyen d'obscurcir son script dans certains cas particuliers ? (ex: je ne veux pas que les personnes qui décompilent le code sache quelle est la méthode de calcul pour augmenter le niveau d'un personnage dans un jeu).
    L'objectif n'est pas de sécuriser, mais de retarder la découverte de cette méthode de calcul.

    Non. Ce n'est pas par là que j'agirais.

    4. Y a-t-il une différence entre Class.forName("Toto") et objetURLClassLoader.loadClass("Toto") ?

    L'une va chercher la classe dans le ClassLoader déjà chargé de ton application Java, l'autre va essayer de la trouver dans un jar où emplacement externe auparavant.

  3. #3
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 326
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste Programmeur

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 326
    Billets dans le blog
    12
    Par défaut
    Bonjour,

    Merci pour votre réponse @grunt2000.

    En faite, pour la première question, je me demandais si dans le cas où Java sauvegarde le .class téléchargé, est-ce que celui-ci est sauvegardé quelque part sur le disque ou non.


    Pour la seconde question :
    Pourriez-vous me dire à quel moment exactement l'URLClassLoader va télécharger le ".jar" qui se trouve à distance, lors de l'instanciation d'URLClassLoader ? Ou bien lors de l'utilisation de la méthode loadClass("nom de ma classe").


    J'aurais 2 nouvelles questions :
    5. Y a t-il une différence de performance entre l'instanciation normale (ex: new MaClasse() ), et l'instanciation via un objet de type Class avec la méthode newInstance() ?

    6. Lorsqu'on dit que le ClassLoader va "charger les classes", est-ce que le ClassLoader va mettre en mémoire une liste de l'emplacement de tous les fichiers .class (ex: { "C:/chemin/Toto.class", "C:/chemin/Tata.class", "C:/chemin/Titi.class" } ), ou bien s'agit-t-il d'autre chose ?


    Merci
    N'hésitez pas à consulter la FAQ Java, lire les cours et tutoriels Java, et à poser vos questions sur les forums d'entraide Java

    Ma page Developpez | Mon profil Linkedin | Vous souhaitez me contacter ? Contacter Gokan EKINCI

  4. #4
    Membre Expert

    Profil pro
    Inscrit en
    Décembre 2011
    Messages
    974
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 974
    Par défaut
    Citation Envoyé par Gugelhupf Voir le message
    5. Y a t-il une différence de performance entre l'instanciation normale (ex: new MaClasse() ), et l'instanciation via un objet de type Class avec la méthode newInstance() ?
    J'ai fait des tests avec différentes différentes classes et différents types d'attributs: je n'ai pas réussi à obtenir une règle (ou une tendance) claire sur les performances de l'instanciation par new, .newInstance() ou par clonage.

    Pourtant dans certains cas, j'obtenais des facteurs 200 voir 500 sur les temps de traitement. Dans d'autres cas, les résultats étaient inversés.

  5. #5
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Citation Envoyé par Gugelhupf Voir le message
    1. Lorsqu'on instancie une classe URLClassLoader, le jar (ou les jars) qui est récupéré, est placé en forme de fichier sur la machine ou bien directement stocké en RAM ?
    Il est lu via la méthode ad-hoc sur la classe URL depuis son emplacement d'origine.
    Citation Envoyé par Gugelhupf Voir le message
    Pourriez-vous me dire quels sont les impacts les plus négatifs lors de l'utilisation des classes URLClassLoader et Class (par étape)
    Bha rien de bien différent de quand tu utilise des class normalement. Ce que tu fais avec URLClassloader, surprise, la jvm le fait aussi avec ton code. Le class loader de base de ton application est souvent déjà un URLClassloader.

    La seule particularité quand tu utilise un classloader séparé, c'est que ton application de base ne vois pas les classes présentes dans le URLClassloader, ces domaines sont séparés.
    3. Considérant que le jar est récupéré à partir du réseau ou internet, pensez-vous que ce soit un bon moyen d'obscurcir son script dans certains cas particuliers ? (ex: je ne veux pas que les personnes qui décompilent le code sache quelle est la méthode de calcul pour augmenter le niveau d'un personnage dans un jeu).
    L'objectif n'est pas de sécuriser, mais de retarder la découverte de cette méthode de calcul.
    Si tu ne veux pas que l'utilisateur connaisse la méthode de calcul, fait le calcul sur le server et pas coté client

    4. Y a-t-il une différence entre Class.forName("Toto") et objetURLClassLoader.loadClass("Toto") ?
    Le premier utilise le classloader de ta classe courante (this.getClass().getClassloader()), le second utilise un classloader spécifique. A part ça, c'est basiquement le même

  6. #6
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 326
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste Programmeur

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 326
    Billets dans le blog
    12
    Par défaut
    Bonjour,

    Citation Envoyé par plawyx Voir le message
    Dans d'autres cas, les résultats étaient inversés.
    Je ne m'attendais pas aux cas où la réflexion/introspection donne de meilleures résultats (niveau performance) que l'écriture normale ( new MaClasse() )




    @tchize_
    Il est lu via la méthode ad-hoc sur la classe URL depuis son emplacement d'origine.
    Je me doute bien qu'il y a une réception de flux de la machine qui utilise URLClassLoader sur la machine source (qui contient les .jar et .class).
    La question que je me pose c'est que fait la JVM exécutant URLClassLoader de ce flux ? Est-ce qu'elle le stocke en RAM, ou bien au format fichier ".class" sur le disque local.
    Si par exemple le Garbage Collector supprimer l'objet URLClassLoader, est-ce que les .jar téléchargés sont supprimés de la RAM, ou bien les fichiers .class restent quelque part sur le disque ?

    7. Donc si je comprends bien (dans l'ordre) :
    1. L'instanciation d'URLClassLoader va télécharger les .jar et .class
    2. La méthode loadClass() va juste permettre de récupérer le type Class<T>
    3. La méthode newInstance() va permettre de créer une nouvelle instance de T

    N'hésitez pas à me rectifier



    8. Est-ce que l'instanciation d'une classe URLClassLoader est synchrone ou asynchrone ? => est-ce que l'instruction new URLClassLoader() est bloquante (attend que le téléchargement soit terminé) ou non ?
    Pourquoi je pose cette question ? C'est simple, notre enseignant nous a dit que les instructions suivantes pouvaient bloquer la JVM :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Image img = getTolKit().getImage(urlImage);
    // getImage() est asynchrone
     
    while(img.getHeigth() == -1){
        // Mettre l'instruction Thread.yield() sinon risque de boucle infinie
    }
    Ce cas de boucle infinie arrive lorsque le thread actif attend un appel système avant de donner la main au thread dans getImage(), sauf qu'aucun appel système n'est effectué dans la boucle while (donc boucle infinie).
    C'est un cas particulier de la JVM qui utilise un algorithme sur les appels systèmes.



    PS: N'hésitez pas à répondre à la question 6. , et ensuite je pense que je passerais en résolu


    Merci
    N'hésitez pas à consulter la FAQ Java, lire les cours et tutoriels Java, et à poser vos questions sur les forums d'entraide Java

    Ma page Developpez | Mon profil Linkedin | Vous souhaitez me contacter ? Contacter Gokan EKINCI

  7. #7
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Citation Envoyé par Gugelhupf Voir le message
    La question que je me pose c'est que fait la JVM exécutant URLClassLoader de ce flux ?
    Elle crée un tableau de URL qu'elle transmet à une classe de type sun.misc.URLClassPath. C'est URLClassPath qui fait le boulot éventuel de connection au serveur web, et son comportement n'est pas documenté.
    Si tu veux t'y plonger, tu peux regarder comment il travaill:

    http://www.docjar.com/html/api/sun/m...Path.java.html

    Mais en gros, il a un comportement qui dépend du type de l'url. Si c'est un fichier local: ouverture en local. Si c'est un folder distance, demande de connexion au serveur web pour chaque classe. Je n'ai pas eu le courage d'aller en détail si c'est un JAR distant, mais il semble qu'il joue sur une connexion restant ouverte avec le serveur et les reprise http pour aller directement à l'indx voulu sans devoir tout garder.
    Citation Envoyé par Gugelhupf Voir le message
    Est-ce qu'elle le stocke en RAM, ou bien au format fichier ".class" sur le disque local.
    ni l'un ni l'autre, normalement, il ne stocke pas

    Citation Envoyé par Gugelhupf Voir le message
    L'instanciation d'URLClassLoader va télécharger les .jar et .class
    non, ça va juste créer un liste d'url stockée quelque part. Sans plus.
    Citation Envoyé par Gugelhupf Voir le message
    la méthode loadClass() va juste permettre de récupérer le type Class<T>
    cette méthode repose sur findClass qui, lui, peut déclencher un téléchargement.
    Citation Envoyé par Gugelhupf Voir le message
    La méthode newInstance() va permettre de créer une nouvelle instance de T
    Oui


    Citation Envoyé par Gugelhupf Voir le message
    est-ce que l'instruction new URLClassLoader() est bloquante (attend que le téléchargement soit terminé)
    Non, elle en télécharge rien.


    Citation Envoyé par Gugelhupf Voir le message
    Pourquoi je pose cette question ? C'est simple, notre enseignant nous a dit que les instructions suivantes pouvaient bloquer la JVM :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Image img = getTolKit().getImage(urlImage);
    // getImage() est asynchrone
     
    while(img.getHeigth() == -1){
        // Mettre l'instruction Thread.yield() sinon risque de boucle infinie
    }
    Il doit réviser son cours. Il n'y a pas de méthode Image.getHeight(). Par contre, il y a une méthode Image.getHeight(ImageObserver). D'ailleurs, là, on te mentionne clairement que tout est asynchrone et que getHeight peut te retourner -1 si ce n'est pas encore connu. Enfin, tu peux passer un ImageObserver pour être notifié. Le problème n'est pas trop le temps du réseau, mais le travail, parfois important, nécessaire pour décoder les images si elles sont grande. Je peux passer 10ms sur les IO pour lire 500k d'un fichier, mais 2 secondes pour faire le décodage...

    Citation Envoyé par Gugelhupf Voir le message
    Ce cas de boucle infinie arrive lorsque le thread actif attend un appel système avant de donner la main au thread dans getImage(), sauf qu'aucun appel système n'est effectué dans la boucle while (donc boucle infinie).
    C'est un cas particulier de la JVM qui utilise un algorithme sur les appels systèmes.
    Je ne sais pas où tu va chercher ça, mais non, l'ImageProducer utilisé derrière n'attends pas que ton programme fasse quoi que ce soit pour décoder. Le Thread.yield est inutile. D'ailleurs, la javadoc de Thread.yield() met en garde contre son utilisation:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    -> C'est juste une indication au scheduler
    -> Il est libre de l'ignorer
    -> Ca "tente" d'améliorer le partage du CPU
    -> C'est rarement adéquat d'utiliser cette méthode
    -> doit être utilisé en combinaison avedes des benchmark et un profiling détaillé indiquant sa nécessité
    -> Peut être utilise pour faciliter le reproduction de certains bugs
    Par contre, si tu veux éviter de gaspiller des cycles dans la boucle active, tu peux utiliser le ImageObserver, c'est bien plus approprié comme méthode

  8. #8
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Je n'ai pas eu le courage d'aller en détail si c'est un JAR distant, mais il semble qu'il joue sur une connexion restant ouverte avec le serveur et les reprise http pour aller directement à l'indx voulu sans devoir tout garder.
    Je viens de faire un sniff réseau par curiosité, il semble que les jar distants, il ne les télécharge qu'une seule fois. Maintenant le comportement concret n'étant pas documenté, difficile de te répondre et surtout, la réponse serait probablement dépendante à la jvm concernée. sur ma jvm ça crée des entrée jar_cache dans le temp, qui sont nettoyés à la sortie.

  9. #9
    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 tchize_ Voir le message
    Je ne sais pas où tu va chercher ça, mais non, l'ImageProducer utilisé derrière n'attends pas que ton programme fasse quoi que ce soit pour décoder. Le Thread.yield est inutile. D'ailleurs, la javadoc de Thread.yield() met en garde contre son utilisation:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    -> C'est juste une indication au scheduler
    -> Il est libre de l'ignorer
    -> Ca "tente" d'améliorer le partage du CPU
    -> C'est rarement adéquat d'utiliser cette méthode
    -> doit être utilisé en combinaison avedes des benchmark et un profiling détaillé indiquant sa nécessité
    -> Peut être utilise pour faciliter le reproduction de certains bugs
    Par contre, si tu veux éviter de gaspiller des cycles dans la boucle active, tu peux utiliser le ImageObserver, c'est bien plus approprié comme méthode
    Attention quand même, getHeight(ImageObserver) n'est pas tenue d'être synchronisée, et la propriété height ou quoi que ce soit permettant de la calculer, n'est pas tenu d'être volatile.
    Conclusion la boucle pourrait bel et bien rester infinie, parce que le thread de la boucle et le thread qui a fini de calculer l'image ne se sont pas synchronisés et la fin du calcul est invisible pour celui qui l'attendait. Thread.yield() ne devrait pas, en principe, y changer quelque chose.

    Du coup, il faut vraiment utiliser le ImageObserver si l'image est utilisable avant que sa taille ait été calculée.

    (En pratique j'ai déjà implémenté des images progressives de ce genre pour démonstration, mais je n'en ai jamais vue fournie avec Java. L'intérêt d'un objet Image dont on ne connaît pas les dimensions me semble rarement pertinent.)
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  10. #10
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Citation Envoyé par thelvin Voir le message
    Attention quand même, getHeight(ImageObserver) n'est pas tenue d'être synchronisée, et la propriété height ou quoi que ce soit permettant de la calculer, n'est pas tenu d'être volatile.
    Conclusion la boucle pourrait bel et bien rester infinie, parce que le thread de la boucle et le thread qui a fini de calculer l'image ne se sont pas synchronisés et la fin du calcul est invisible pour celui qui l'attendait.
    Il me semble que ce ne serait vrai si on faisait un while (image.height). Le fait d'appeler une méthode force le thread à bel et bien lire la valeur dans la classe et non pas dans une copie locale au thread courant. Il me semble que le cache concerné est limité au scope de la méthode en cours. Rentrer dans une méthode crée un nouveau scope.

  11. #11
    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
    Le modèle de mémoire Java ne garantit rien de ce genre, le thread qui boucle pourrait par exemple lire cette valeur dans un cache qui lui est propre, et l'autre thread l'écrire dans la mémoire centrale et son propre cache.
    Le cache de la boucle ne se resynchronisant donc que lorsqu'il s'en trouve obligé, potentiellement jamais.

    Sinon, synchronized servirait encore à la limite à pas mal de trucs. Mais volatile, non.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  12. #12
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 326
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste Programmeur

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 326
    Billets dans le blog
    12
    Par défaut
    Bonjour,


    Merci tchize_ pour ces explications (et précisions) concernant le fonctionnement d'URLClassLoader !



    @tchize_
    Je ne sais pas où tu va chercher ça, mais non, l'ImageProducer utilisé derrière n'attends pas que ton programme fasse quoi que ce soit pour décoder. Le Thread.yield est inutile. D'ailleurs, la javadoc de Thread.yield() met en garde contre son utilisation
    Je ne l'invente pas
    L'objectif ici était de "rendre synchrone une méthode asynchrone avec une boucle while" (chose qu'il ne faut pas faire, car relève de la mauvaise conception, et il l'a dit).

    Dans ce programme on a 2 threads :
    1. Celui du main()
    2. Celui du getImage()


    Il existe plusieurs algorithme d'ordonnancement au niveau de la JVM, ils nous en a parlé de 3 :
    1. Time-slicing, qui consiste à accorder un temps déterminé (ex: 10ms) à chaque thread.
    2. Algorithme qui attend un appel système avant de rendre la main à l’ordonnanceur.
    3. Autres paramètres (ex: niveau de priorité du thread)

    Maintenant si par malchance on tombe sur l'algorithme n°2, et qu'on se trouve dans le thread n°1 ( celui du main() ), alors on risque d'avoir une boucle infinie car l'ordonnanceur ne va jamais rendre le thread n°2 actif tant qu'il n'aura pas rencontré d'appel système (ex: fonction lecture de flux, socket etc...).

    La solution c'est de faire appel à l'ordonnanceur (qui utilise l'algorithme d'ordonnancement n°2) pour changer de thread, soit en utilisant Thread.yield() ou bien en effectuant un appel système.


    PS: Concernant l'exemple que mon enseignant a montré, je pense qu'il savait que la méthode Image.getHeight(ImageObserver) existait, mais il a voulu faire simple c'est tout... Sinon je vais lui faire part de ta remarque concernant Thread.yield()



    @thelvin
    Le modèle de mémoire Java ne garantit rien de ce genre, le thread qui boucle pourrait par exemple lire cette valeur dans un cache qui lui est propre, et l'autre thread l'écrire dans la mémoire centrale et son propre cache.
    Il me semble que 2 threads qui exploitent un même objet, ont tout les deux accès aux mêmes valeurs (attributs de l'objet).
    Si thread n°1 modifie la valeur d'un attribut de l'objet, thread n°2 devrait pouvoir récupérer la valeur modifiée par thread n°1 avec un getter sur l'objet non ?
    Sinon quel serait l'intérêt de "synchronized".



    PS: Si je pouvais avoir une confirmation pour la question 6. ce serait top


    PS2: J'utilise le terme français "ordonnanceur" pour scheduler.


    Merci
    N'hésitez pas à consulter la FAQ Java, lire les cours et tutoriels Java, et à poser vos questions sur les forums d'entraide Java

    Ma page Developpez | Mon profil Linkedin | Vous souhaitez me contacter ? Contacter Gokan EKINCI

  13. #13
    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 Gugelhupf Voir le message
    Il me semble que 2 threads qui exploitent un même objet, ont tout les deux accès aux mêmes valeurs (attributs de l'objet).
    Si thread n°1 modifie la valeur d'un attribut de l'objet, thread n°2 devrait pouvoir récupérer la valeur modifiée par thread n°1 avec un getter sur l'objet non ?
    En pratique je suis sûr que c'est souvent ce qui se passe sur les architectures que nous connaissons bien.

    En théorie le modèle de données de Java ne garantit rien de ce genre. À partir du moment où il existe des systèmes de cache de mémoire, qui ne soient pas partagés entre les threads, le but est de s'en servir. À partir de là faire en sorte que deux threads voient la même chose peut nécessiter de synchroniser les caches. C'est un mécanisme coûteux qu'il n'y a pas de raison d'invoquer si cela n'est pas nécessaire, donc pas demandé explicitement.

    Citation Envoyé par Gugelhupf Voir le message
    Sinon quel serait l'intérêt de "synchronized".
    Bah justement c'est un moyen de le demander explicitement. Tu te serais pas emmêlé les pinceaux ?

    (Et en l'occurrence, l'emploi de volatile semble plus adapté, une exclusion mutuelle n'étant pas pertinente.)

    Citation Envoyé par Gugelhupf Voir le message
    6. Lorsqu'on dit que le ClassLoader va "charger les classes", est-ce que le ClassLoader va mettre en mémoire une liste de l'emplacement de tous les fichiers .class (ex: { "C:/chemin/Toto.class", "C:/chemin/Tata.class", "C:/chemin/Titi.class" } ), ou bien s'agit-t-il d'autre chose ?
    Nope. Il va lire les classes à partir de leur emplacement (fichier ou non,) décoder leur format byteCode, effectuer leur initialisation, résoudre leurs dépendances, et garder en mémoire cette version décodée du byteCode, associé au nom qualifié de ces classes.

    Charger une classe n'a rien à voir avec des fichiers. Notamment la classe pourrait venir d'une socket réseau qui n'a pas de logique fichier.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  14. #14
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Citation Envoyé par Gugelhupf Voir le message
    Il existe plusieurs algorithme d'ordonnancement au niveau de la JVM, ils nous en a parlé de 3 :
    1. Time-slicing, qui consiste à accorder un temps déterminé (ex: 10ms) à chaque thread.
    2. Algorithme qui attend un appel système avant de rendre la main à l’ordonnanceur.
    3. Autres paramètres (ex: niveau de priorité du thread)
    Je veux bien croire ça, mais j'attends qu'on me pointe sur une doc d'oracle qui précise les technique d'ordonnancement...
    En fait, l'ordonnancement des threads n'est pas fait par la jvm mais par l'OS, parce qu'il est plus à même de le faire. A moins que tu n'utilise des green thread, mais je ne pense même pas que les jvm actuelles soient encore capable de faire des green threads.

    Au niveau des OS
    Les cas 1 et 3 ne posent aucun problème à une boucle active (mis à part qu'elle bouffe du CPU)
    Le cas numéro 3 n'existe plus depuis windows 3.11 où, il est vrai, l'ordonnanceur était tellement basique qu'une application pourvait garder la main sur le CPU sans jamais le rendre aux autres.

  15. #15
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 326
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste Programmeur

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 326
    Billets dans le blog
    12
    Par défaut
    Citation Envoyé par thelvin Voir le message
    Nope. Il va lire les classes à partir de leur emplacement (fichier ou non,) décoder leur format byteCode, effectuer leur initialisation, résoudre leurs dépendances, et garder en mémoire cette version décodée du byteCode, associé au nom qualifié de ces classes.
    Cela signifie bien que ClassLoader va garder en mémoire l'emplacement des classes (que ce soit un fichier en local ou sur le réseau).
    Que signifie "garder en mémoire cette version décodée du bytecode" ? Est-ce que cela signifie que la JVM stocke en RAM une version améliorée du bytecode, ou bien ce décodage se traduit par le stockage de code assembleur en RAM ?


    @tchize_
    Le cas numéro 3 n'existe plus depuis windows 3.11
    Il se pourrait en fait qu'il s'agisse en fait du numéro 2, selon mon enseignant.


    Merci
    N'hésitez pas à consulter la FAQ Java, lire les cours et tutoriels Java, et à poser vos questions sur les forums d'entraide Java

    Ma page Developpez | Mon profil Linkedin | Vous souhaitez me contacter ? Contacter Gokan EKINCI

  16. #16
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Citation Envoyé par Gugelhupf Voir le message
    Cela signifie bien que ClassLoader va garder en mémoire l'emplacement des classes (que ce soit un fichier en local ou sur le réseau).
    Pas vraiment. Une fois la class chargée par le classloader, il ne retiens pas son origine. Par contre, il retient qu'elle a été chargée à partir de tel classloader.
    Citation Envoyé par Gugelhupf Voir le message
    Que signifie "garder en mémoire cette version décodée du bytecode" ? Est-ce que cela signifie que la JVM stocke en RAM une version améliorée du bytecode, ou bien ce décodage se traduit par le stockage de code assembleur en RAM ?
    Ca veux dire qu'à partir du .class elle crée un représentation en mémoire qui permet d'exécuter les byecode contenu dans ce .class. Que ce soit le bytecode en lui même qu'elle garde, ou une version tripatouillée par le JIT ou encore le code natif convertis n'est précisé nulle part et n'est pas prévisible.

Discussions similaires

  1. Question sur URLClassLoader
    Par xps1616 dans le forum Général Java
    Réponses: 8
    Dernier message: 21/02/2013, 10h49
  2. Question sur construction de classe avec JFrame
    Par cmako dans le forum Agents de placement/Fenêtres
    Réponses: 11
    Dernier message: 28/03/2007, 11h42
  3. Réponses: 2
    Dernier message: 04/12/2005, 21h10
  4. Question sur la classe InputStream
    Par Zec Merquise dans le forum Entrée/Sortie
    Réponses: 5
    Dernier message: 26/10/2005, 02h36
  5. Question sur exports et les classes (pour une dll)
    Par DjPoke dans le forum Langage
    Réponses: 7
    Dernier message: 08/08/2005, 19h25

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