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 :

Tutoriel sur une introduction à l'API Java 8 Concurrency, application à ExecutorService


Sujet :

Java

  1. #1
    Membre chevronné

    Homme Profil pro
    Ingénieur R&D en informatique
    Inscrit en
    Août 2011
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Ingénieur R&D en informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2011
    Messages : 313
    Points : 1 855
    Points
    1 855
    Par défaut Tutoriel sur une introduction à l'API Java 8 Concurrency, application à ExecutorService
    Bonjour,

    L'article a pour but de présenter la bibliothèque java.util.concurrent et plus précisément l'API ExecutorService. Il met l'accent sur l'illustration de cette API avec les concepts Java 8.

    https://gkemayo.developpez.com/tutor...8-concurrency/

    Qu'en pensez-vous?

    Retrouver les meilleurs cours et tutoriels pour apprendre la programmation en Java

  2. #2
    Candidat au Club
    Homme Profil pro
    Développeur Java
    Inscrit en
    Août 2019
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Août 2019
    Messages : 2
    Points : 3
    Points
    3
    Par défaut
    Bonjour,

    Merci pour cet article.
    Cependant j'aimerais remonter quelques erreurs, et faire quelques remarques, c'est possible ?

    Cordialement

  3. #3
    Membre chevronné

    Homme Profil pro
    Ingénieur R&D en informatique
    Inscrit en
    Août 2011
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Ingénieur R&D en informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2011
    Messages : 313
    Points : 1 855
    Points
    1 855
    Par défaut
    Bonjour Bolojul,

    Je suis bien curieux de lire ces erreurs De quel type d'erreurs parles-tu ?
    Je reste à l'écoute.

    Cordialement,

  4. #4
    Candidat au Club
    Homme Profil pro
    Développeur Java
    Inscrit en
    Août 2019
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Août 2019
    Messages : 2
    Points : 3
    Points
    3
    Par défaut
    Bonjour MisterKool,

    Oui il me semble qu'il y a quelques erreurs plus ou moins importantes. A ta dispo pour en discuter. Voici ce que j'ai pu relever :

    IV-A

    Tu indiques : Nous insistons sur le terme publique, car avec Java 8, on peut désormais retrouver des méthodes privées dans une interface.

    En java 8, les interfaces peuvent avoir des méthodes public, static, et default. Les méthodes privées viennent à partir de java 9.


    V-A-2. Méthode submit()

    Ici il y a une mauvaise utilisation de la méthode awaitTermination :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    counterThreadService.awaitTermination(3, TimeUnit.SECONDS);
    if (sommeProduits.isDone()) {
    	System.out.println("Nombre total de produits dans le magasin : " + sommeProduits.get());
    }
    En effet la documentation précise bien : Blocks until all tasks have completed execution after a shutdown request, or the timeout occur
    Or ici aucun shutdown request n'est effectué ! (il est fait après)

    La conséquence, c'est qu'il va attendre 3 secondes, même si la tâche se termine bien avant. En fait c'est exactement la même chose que si tu avais mis : sleep(3000).
    Pour ne pas attendre 3 secondes, mais au maximum 3 secondes (c'est à dire dès que la tâche est terminée si celle ci se termine avant 3 secondes), il faut :
    - soit faire un shutdown avant le awaitTermination:
    - soit remplacer les 4 lignes ci dessus par un simple sommeProduits.get(3, TimeUnit.SECONDS) : On va bloquer au maximum 3 secondes. Si la tâche se termine avant, on aura le résultat. Si la tâche se termine après, il faut catcher un TimeoutException


    V-B-2. Méthode invokeAny()

    L'exemple et le use case utilisé ici n'est pas du tout adapté à l'utilisation de invokeAny, ce qui fait que le résultat produit pourra être faux.
    Tu utilises invokeAny pour rechercher en parallèle une valeur dans deux ensembles. Tu supposes alors que le premier qui a trouvé la valeur, retournera son résultat.
    Or ce n'est pas le premier qui trouve la valeur qui retourne, mais le premier qui finit sa recherche !! Et ça change tout. Si dans l'ensemble 1 / thread 1, tu as la valeur 1500 recherchée. Et dans l'ensemble 2 / thread 2 tu n'as pas cette valeur. Et que thread 2 termine sa recherche avant thread 1, tu auras alors le message "Aucun thread n a trouvé le CA 1500 recherché". Alors que cette valeur existe dans l'ensemble 1 !

    Le cas est très facile à reproduire. Tu crées une liste de 500 valeurs non pas random, mais fixes, un ensemble contenant la valeur recherchée et l'autre non. Tu lances plusieurs fois ton programme, et tu verras que le résultat diffère alors que la liste est fixe, et donc que le résultat devrait être toujours le même.

    Pour corriger, il suffit pour les thread ne trouvant pas la valeur, de lancer une exception, et non de renvoyer le message "Aucun thread n a trouvé le CA 1500 recherché". La documentation précisant :
    Executes the given tasks, returning the result of one that has completed successfully (i.e., without throwing an exception)
    - Si une tâche se termine sans erreurs, c'est qu'elle a trouvé la valeur
    - Si aucune tâche ne trouve la valeur, invokeAny lancera une ExecutionException


    V-D-2. Méthode scheduleWithFixedDelay()

    Même remarque pour le awaitTermination qui ne sert pas à grand chose si shutdown n'a pas été appelé. Un simple sleep permet d'attendre le temps voulu.


    V-D-3. Méthode scheduleAtFixedRate()

    Tu indiques : que si l'on defini une période de trois minutes par exemple, que la durée d'exécution d'une tâche dure quatre minutes, alors toutes les 3 minutes un nouveau thread sera créé, quitte à avoir plusieurs threads en exécution parallèles

    C'est incorrect, aucune thread n'est crée pour compenser une tâche qui serait plus longue que le rate indiqué. Si le cas arrive, la tâche suivante se lance dès que la tâche précédente est terminée.
    Tu peux le lire dans la documentation de scheduleAtFixedRate :
    If any execution of this task takes longer than its period, then subsequent executions may start late, but will not concurrently execute

    Et de manière générale (c'est un détail !), pour faire des opérations sur les streams contenant des types primitifs (int et long), tu utilises reduce pour faire des opérations simples comme min et sum, alors qu'il est plus efficace (normalement moins d'autoboxing) et plus lisible d'utiliser les méthodes sum() et min() sur les streams primitifs IntStream et LongStream, obtenu par les méthodes mapToInt et mapToLong sur les stream<Integer> et stream<Long>.

    En espérant avoir pu aider

    Cordialement

  5. #5
    Membre chevronné

    Homme Profil pro
    Ingénieur R&D en informatique
    Inscrit en
    Août 2011
    Messages
    313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vienne (Poitou Charente)

    Informations professionnelles :
    Activité : Ingénieur R&D en informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2011
    Messages : 313
    Points : 1 855
    Points
    1 855
    Par défaut
    Bonjour Bolojul,

    J'étais sceptique au départ, mais force est de constater que tes remarques sont pertinentes.

    J'ai pris en compte tes remarques et répercuté cela dans l'article.

    Pour ta remarque sur Java 8 et sur les méthodes privées, j'ai dû effectivement me mêler les painceaux avec Java 9. Je prise que j'ai écrit l'article à une date où Java 9 était déjà sortie.

    Pour ta remarque sur awaitermination de la section V-D-2, c'est fait exprès car l'idée est de voir le thread écrire ses résultats. On aurait pu utiliser sleep, mais c'est un point de vue.

    Enfin, pour la gestion des Stream et ses fonctions, tu as raison, mais mon but n'est pas d'optimiser le code. J'ai expressément utilisé les Wrapper des types primitifs (int, long) pour utiliser les fonctions un peu avancées des Streams (comme reduce) afin de vulgariser ces dernières, c'est un choix. Si tu regardes d'ailleurs les différents blocs de code, tu verras qu'il y a des instructions que j'aurai pu compacter et optimiser. Mais je les ai laissé detailler par souci de pédagogie et clarté pour le lecteur.

    Pour le reste tu as totalement raison et je t'en remercie pour ton investissement et tes remarques.

    Cordialement.

Discussions similaires

  1. Réponses: 0
    Dernier message: 31/10/2014, 09h37
  2. Réponses: 21
    Dernier message: 12/10/2014, 12h28
  3. Réponses: 0
    Dernier message: 09/01/2005, 12h00

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