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 vs Callable


Sujet :

Concurrence et multi-thread Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    65
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 65
    Par défaut Thread vs Callable
    Bonjour,

    j'ai une exécution à faire en parallèle.
    J'avais donc créé une classe qui étendait de Thread.
    Le problème est que cette exécution peut remonter des exceptions or il est impossible de modifier la signature de la méhode run() de l'interface Runnable.

    J'ai cherché un peu et Callable semble répondre à mon besoin, le hic est que je ne parviens pas à faire une réelle exécution en parallèle.
    Quand je lance ma 1ère classe Callable puis ma seconde, le traitement de la 1ère s'effectue, puis une fois terminée le traitement de la seconde commence.

    J'aurai donc besoin de vos conseils car je ne suis pas sûr d'utiliser Callable comme il se doit.

    Voici 2 exemples :
    - le 1er utilise Thread et quand on lance le programme on voit bien dans la console que les exécutions des 2 threads sont faites en parallèle
    - le 2nd utilise Callable (qui pourra lever une exeception en modifiant sa signature) mais quand on l'exécute on voit dans la console que la 1ère exécution s'effectue puis séquentiellement la 2nde.

    L'affichage de l'identifiant du thread courant montre également qu'en utilisant les Threads on a bien 3 identifiants différents (1 pour le main, 1 deuxième pour le 1er Thread et un 3ème pour le 2nd Thread) alors que dans le 2ème exemple on a seulement 1 seul identifiant pour les 3 entités (main + 1er Callable + 2nd Callable) d'où ma déduction que les exécutions se font en séquentiel ....

    1er exemple : utilisant Thread
    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
     
    public class MyThread extends Thread {
    	private String name;
     
    	public MyThread(String pName) {
    		super();
    		name = pName;
    	}
     
    	public void run() {
    		System.out.println("ID " + name + " ===> "
    				+ Thread.currentThread().getId());
    		for (int i = 0; i < 100; i++) {
    			System.out.println(name + "Iteration " + i);
    			try {
    				Thread.sleep(1);
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    		}
    	}
     
    	/**
             * @param args
             */
    	public static void main(String[] args) {
    		System.out.println("ID MAIN ===> " + Thread.currentThread().getId());
    		MyThread t1 = new MyThread("Thread 1 ");
    		t1.start();
    		MyThread t2 = new MyThread("Thread 2 ");
    		t2.start();
    	}
     
    }
    2ème exemple : utilisant Callable
    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
    35
    36
    37
    38
     
    import java.util.concurrent.Callable;
     
    public class MyCallable implements Callable {
    	private String name;
     
    	public MyCallable(String pName) {
    		super();
    		name = pName;
    	}
     
    	public Thread.State call () {
    		System.out.println("ID " + name + " ===> " + Thread.currentThread().getId());
    		for (int i=0; i<100; i++) {
    			System.out.println(name + "Iteration " + i);
    			try {
    				Thread.sleep(1);
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}
     
    		return Thread.State.TERMINATED;
    	}
     
    	/**
             * @param args
             */
    	public static void main(String[] args) {
    		System.out.println("ID MAIN ===> " + Thread.currentThread().getId());
    		MyCallable t1 = new MyCallable("Thread 1 ");
    		t1.call();
    		MyCallable t2 = new MyCallable("Thread 2 ");
    		t2.call();
    	}
     
    }
    Ma question est donc comment faire un réel traitement multithread avec 2 exécutions en parallèle tout ayant la possibilité de remonter des exceptions de ces traitements.

  2. #2
    Membre émérite

    Étudiant
    Inscrit en
    Octobre 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2007
    Messages : 510
    Par défaut
    bonjour,

    pour la mérhode avec thread , je pense que tu devrai entourer toute ta méthode run() dans le try catch pour pouvoir faire remonter l'exception correctement... comme ca :

    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
     
    public class MyThread extends Thread {
        private String name;
        private Exception ex;
     
        public MyThread(String pName) {
            super();
            name = pName;
        }
        public void run() {
            try {
                System.out.println("ID " + name + " ===> "
                        + Thread.currentThread().getId());
                for (int i = 0; i < 100; i++) {
                    System.out.println(name + "Iteration " + i);
                        Thread.sleep(1);
     
                }
            } catch (InterruptedException e) {
                ex = e;
            }
        }
     
        public Exception getEx() {
            return ex;
        }
        public static void main(String[] args) {
            System.out.println("ID MAIN ===> " + Thread.currentThread().getId());
            MyThread t1 = MyThread New("Thread 1 ");
            t1.start();
            MyThread t2 = new MyThread("Thread 2 ");
            t2.start();
     
            try {
                t1.join();
                t2.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
     
            Exception ex1 = t1.getEx();
            Exception ex2 = t2.getEx();
            if (ex1 != null) {
                System.out.println("Thread 1 has throws an exception !");
                ex1.printStackTrace();
            } else {
                System.out.println("Thread 1 has not throws an exception !");
            }
            if (ex2 != null) {
                System.out.println("Thread 2 has throws an exception !");
                ex1.printStackTrace();
            } else {
                System.out.println("Thread 2 has not throws an exception !");
            }
        }
    }
    voila tiens moi au courant.
    a +

  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,


    En effet tu utilises mal les Callables. Tout comme on ne doit pas appeler directement la méthode run() mais utiliser start() qui lance le thread, on ne doit pas appeler directement call() sinon le traitement se fait directement dans le thread courant...

    Avec Callable le plus simple est de passer par les executors :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    	public static void main(String[] args) {
    		System.out.println("ID MAIN ===> " + Thread.currentThread().getId());
     
    		ExecutorService executor = Executors.newCachedThreadPool();
     
    		MyCallable t1 = new MyCallable("Thread 1 ");
    		Future<?> f1 = executor.submit(t1);
     
    		MyCallable t2 = new MyCallable("Thread 2 ");
    		Future<?> f2 = executor.submit(t2);
    	}
    Les executors permettent de gérer les threads. Ainsi par exemple newCachedThreadPool() te renvoi un exécuter qui utilise un cache pour exécuter les tâches de fond (et peu donc les réutiliser en cas de besoin).
    Regarde du coté de la classe Executors qui propose des méthodes statiques pour créer les différents types d'exécutors...

    Quand à Future, elle permet de manipuler ton Callable pendant et après son exécution (état, valeur de retour ou exception à la fin du traitement, etc.)

    a++

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    65
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 65
    Par défaut
    Merci beaucoup pour vos réponses.

    Effectivement j'utilisais mal les Callable, encapsulé dans un Executors tout s'exécute bien en paralléle.

    Je trouve que la 1ère proposition n'est pas très jolie mais d'un autre côté l'utilisation de Callable n'est pas intuitive si par exemple je veux pouvoir gérer des pauses sur mon thread de plus il faut créer bcp d'objets pour simplement exécuter un processus en parallèle je trouve cela dommage dans mon cas.

    Je pense opter finalement pour la 1ère proposition.

  5. #5
    Membre émérite

    Étudiant
    Inscrit en
    Octobre 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2007
    Messages : 510
    Par défaut
    ravi d'avoir pu t'aider

    PS : pense a si c'est pas déja fait

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

Discussions similaires

  1. [THREAD] TypeError: NoneType' object is not callable
    Par flolebreton dans le forum Général Python
    Réponses: 2
    Dernier message: 24/06/2013, 14h49
  2. threads callable pas executer en parallele
    Par dumoulex dans le forum Concurrence et multi-thread
    Réponses: 4
    Dernier message: 20/04/2011, 14h35
  3. Tri multi-threadé
    Par Tifauv' dans le forum C
    Réponses: 8
    Dernier message: 28/06/2007, 09h00
  4. Réponses: 5
    Dernier message: 12/06/2002, 15h12
  5. [Kylix] Pb de Thread !!
    Par Anonymous dans le forum EDI
    Réponses: 1
    Dernier message: 25/04/2002, 13h53

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