Bonjour,
Je cherche à récupérer le statut de mes Treads afin de pouvoir afficher dans un tableau leurs état d'avancement (En cours/Terminé). Seulement je ne sais pas comment procéder, avez-vous des pistes à exploiter?
Cordialement.
Bonjour,
Je cherche à récupérer le statut de mes Treads afin de pouvoir afficher dans un tableau leurs état d'avancement (En cours/Terminé). Seulement je ne sais pas comment procéder, avez-vous des pistes à exploiter?
Cordialement.
Je viens de trouver la fonction .isTerminated() qui permet de retourner True si le Thread est fini. Peut-etre que je peux utiliser cela en plus de la fonction .isShutdown() pour vérifier si le Thread n'a pas crash?
euh ... ça c'est des méthodes d'ExecutorService pas de Thread ....
à un plus bas niveau voir getState()
mais si c'est pour attendre voir join()
Thread.isAlive() aussi me paraissait bien
(Les "ça ne marche pas", même écrits sans faute(s), vous porteront discrédit ad vitam æternam et malheur pendant 7 ans)
N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
Mon objet est de type ThreadPoolExecutor je n'ai donc pas les fonction que vous citez
(je reprend un code qui n'est pas le miens à l'origine donc j'essaye également de comprendre comment il fonctionne)
Ouais mais tu as passé quoi a cet executor a ton avis ? Des threads... qui elles ont le status. Il faut donc se debrouiller pour recuperer la liste des thread (ou runnable) que le pool contiendrait encore... ou garder une liste en mémoire.
(Les "ça ne marche pas", même écrits sans faute(s), vous porteront discrédit ad vitam æternam et malheur pendant 7 ans)
N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
Salut,
On ne peut pas récupérer les threads d'un ThreadPoolExecutor directement (surtout qu'ils sont encapsulés dans un Worker, lui-même inaccessible). Modifier la ThreadFactory pour qu'elle stocke les Threads créés risque d'accumuler des références à des threads morts inutilement. Personnellement, je fournirais au ThreadPoolExecutor une fabrique qui affecte un ThreadGroup spécifique identifié, et j'utiliserais ce ThreadGroup pour récupérer les Threads.
A noter que si on voulait avoir les états de tous les Threads de l'application, autant utiliser ManagementFactory.getThreadMXBean().
L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
Nouveau sur le forum ? Consultez Les Règles du Club.
C'est plus ou moins ce que j'ai essayer de faire :
Je n'ai absoluement aucune idée si vais sur la bonne voie ou si je suis à côté de la plaque, la notion de Threads m'est nouveau depuis hier
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 if(executorPool.submit(uneTask).isDone()){ etatThread = "Terminé"; }else{ etatThread = "En cours"; }![]()
Il n'y a pas de relation directe entre les tâches et les threads, sauf cas spécifique. Un pool de threads peut être basé sur un Thread unique (toutes les tâches sont exécutées les unes après les autres par un seul Thread)), plusieurs Threads (qui se partagent les tâches) de "vie infinie", plusieurs Threads recréés/détruits au besoin, ou éventuellement autre chose...
Ce sont les états des tâches ou des threads qui t'intéresse ?
L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
Nouveau sur le forum ? Consultez Les Règles du Club.
Pour faire précis, je travail sur un extraction de données de plusieurs pages, simultanément.
Si j'ai bien compris l'intention du développeur, il lance une multitude de Thread pour extraire les pages et non pas un seul qui itère sur chaque page. On me demande de rajouter dans un tableau coter utilisateur l'avancement de l'extraction car sinon vu que cela s'effectue en taches de fond, celui-ci n'a aucune information sur sont état. Sachant que l'extraction ne dure pas 5 sec mais peut au contraire durer plusieurs heures).
C'est pourquoi j'étais à la recherche d'un moyen afin de récupérer les état des Threads pour savoir si ils étaient finis ou non et ainsi le notifier dans le tableau.
plutôt que de chercher l'état des Threads tu ne peux pas ajouter à tes objets Runnable/Callable un moyen pour les interroger sur l'état d'avancement de leur exécution?
Je pense que c'est plutôt l'état des pages qu'il te faudrait récupérer : si la granularité est de l'ordre de la page, tu peux utiliser isDone() pour savoir qu'une page est terminée (mais attention, si isDone() est faux, ça ne veut pas dire que la page est en cours de traitement, parce qu'une tâche peut être annulée, ou la tâche peut avoir planté). Est-ce que tu peux modifier la classe utilisée pour gérer la tâche ? Si oui, tu peux ajouter dans son code un état, que tu fais toi même progresser par le code (tu peux même ajouter une petite gestion évènementielle pour suivre automatiquement les changements d'états par écouteur) (EDIT : comme le propose @professeur shadoko à l'instant).
Par exemple, à partir de cette abstraction :
Tu créés un composant spécifique pour gérer tes tâches (ici, j'ai supposé que la classe qui représentait une page était Page) :
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 public abstract class AbstractRunnableTaskManager<T extends Enum<T>, P> { private List<IStateListener<T, P>> listeners; /** * */ public AbstractRunnableTaskManager() { listeners = new ArrayList<IStateListener<T, P>>(); } public synchronized void addListener(IStateListener<T, P> listener) { if ( !listeners.contains(listener) ) { listeners.add(listener); } } public synchronized void removeListener(IStateListener<T, P> listener) { if ( !listeners.contains(listener) ) { listeners.add(listener); } } protected void fireChangeState(T state, P parameters) { synchronized (listeners) { for(IStateListener<T, P> stateListener : listeners) { stateListener.changeState(state, parameters); } } } public Runnable createTask(P parameters) { return new RunnableTask(parameters); } public static interface IStateListener<T extends Enum<T>, P> { void changeState(T state, P parameters); } protected abstract void run(RunnableTask task); protected final class RunnableTask implements Runnable { private final P parameters; private T state; public RunnableTask(P parameters) { this.parameters=parameters; } @Override public final void run() { AbstractRunnableTaskManager.this.run( this ); } public final void setState(T state) { this.state=state; } public final T getState() { return state; } public P getParameters() { return parameters; } } }
Et pour l'appel, 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
21
22
23
24
25
26
27
28
29 public class PageTaskManager extends AbstractRunnableTaskManager<PageTaskManager.PageLifeCycle, Page> { // les différentes étapes du processus de traitement d'une page (c'est un exemple) public enum PageLifeCycle { STARTING, RUNNING, FINISHED; } @Override protected void run(RunnableTask task) { Page page = task.getParameters(); task.setState(PageLifeCycle.STARTING); // faire quelque chose task.setState(PageLifeCycle.RUNNING); // faire quelque chose task.setState(PageLifeCycle.FINISHED); } }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 PageTaskManager pageTaskManager = new PageTaskManager(); pageTaskManager.addListener((s, p) -> System.out.println("state " + s + " pour la page " + p)); // exemple qui écrit dans la console, mais là tu pourras mettre à jour une JTable, pour suivre les différents pages et l'avancement de leur traitement... for(Page page : pages) { executorService.submit( pageTaskManager.createTask(page) ); }
L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
Nouveau sur le forum ? Consultez Les Règles du Club.
J'ai vraiment du mal à saisir la chose :s
Voilà ce que j'ai essayer de faire pour le moment, j'ai peur de mal comprendre le code de mon prédécesseur, et je suis plutôt débutant en développement donc c'est assez flou pour moi
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 public class TaskExtractorService { private static final Logger LOGGER = LoggerFactory.getLogger(TaskExtractorService.class); public TaskExtractorService() { super(); } public String executeJob(final EntrepriseRequestData requetePoste, Client esClient, EntrepriseRequestProperties mRequestProperties, String path) throws InterruptedException { String data ="{}"; Map<String, Object> dataPostMap = requetePoste.getRequetesPoster(); EntrepriseRejectedExecutionHandler rejectionHandler = new EntrepriseRejectedExecutionHandler(); ThreadFactory threadFactory = Executors.defaultThreadFactory(); ThreadPoolExecutor executorPool = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(), 10, 150, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(Integer.valueOf(String.valueOf(dataPostMap.get(RequestHelper.NBRE_PAGE)))), threadFactory, rejectionHandler); String etatThread; int nbreTotalPage = Integer.valueOf(String.valueOf(dataPostMap.get(RequestHelper.NBRE_PAGE))) ; int pageSize = Integer.valueOf(String.valueOf(dataPostMap.get(RequestHelper.PAGE_SIZE))) ; List<String> lstItem = new ArrayList<String>(nbreTotalPage); for(int i=1; i<nbreTotalPage+1; i++){ EntrepriseWorkerTask uneTask = new EntrepriseWorkerTask("iteration " +i ,esClient,requetePoste, mRequestProperties, i, pageSize,path,lstItem,nbreTotalPage); executorPool.submit(uneTask); if(executorPool.submit(uneTask).isDone()){ etatThread = "Terminé"; return etatThread; }else{ etatThread = "En cours"; return etatThread; } } try{ ObjectMapper mapper = new ObjectMapper(); executorPool.shutdown(); data = mapper.writeValueAsString(lstItem); if(LOGGER.isDebugEnabled()){ } } catch (JsonGenerationException e) { if(LOGGER.isErrorEnabled()){ LOGGER.error("Erreur de serialisation ", e ); } } catch (JsonMappingException e) { if(LOGGER.isErrorEnabled()){ LOGGER.error("Erreur de serialisation ", e ); } } catch (IOException e) { if(LOGGER.isErrorEnabled()){ LOGGER.error("Erreur de serialisation ", e ); } } return data; } }
Salut,
Les tâches soumises à l'exécuteur (ici, un pool de threads de 10 threads maximum) sont exécutées en parallèle (10 tâches maximum exécutées, les autres étant mise en attente tant qu'il n'y a pas de thread disponible). Au retour de l'appel de submit, la tâche n'est pas forcément terminée. Il y a très peu de probabilité qu'elle le soit en fait, puisqu'elle est censée prendre un certain temps, même s'il y a un thread disponible pour l'éxécuter : en tout cas, on ne doit pas compter dessus. Donc le test qui teste isDone() aura quasiment 100% de chance de passer dans le else et donc de quitter la méthode dès après la soumission de la première tâche. Les autres tâches ne seront donc jamais créées, jamais soumises, donc jamais exécutées. L'executor va continuer à tourner, puisqu'on ne l'arrêtera pas, et tu auras pour résultat définitif "En cours".
En plus, dans ta boucle, comme tu fais 2 fois submit de la même tâche, la première sera exécutée 2 fois.
Tu n'as pas indiqué quel type d'interface graphique tu avais besoin (SWING, JAVAFX, SWT, WEB...CONSOLE... ?), mais peu importe sur le principe. Tu dois penser en "exécution paralélisée" : d'un côté tu as un affichage, de l'autre côté un service d'exécution qui exécute des tâches, qui vont prendre leur temps, et se terminer à leur rythme. Donc tu vas avoir un affichage à mettre à jour, régulièrement, au fur et à mesure, que des tâches se terminent.
Si le but est de juste savoir que les tâches sont terminées, tu peux utiliser le fait que la méthode get() attend que la tâche soit terminée pour répondre. Si tu as besoin d'une progression avec plus d'étapes, il te faudra une solution comme j'ai indiquée (gérer la progression dans la tâche).
Donc si tu as juste besoin de savoir quant les tâches sont terminées, le moyen le plus simple de le faire est :
Attention, avec cette méthode, on n'affiche (dans la console pour l'exemple) le résultat que après que toutes les tâches sont soumises à l'exécuteur : si la soumission de toutes les tâches durent plus longtemps que l'exécution des premières tâches, tu n'auras pas l'affichage au fur et à mesure de la terminaison de ces premières tâches. Pour le faire, il faut également gérer en parallèle le parcourt de la liste. Si tu es débutant, ça commence à devenir plus difficile : la solution que j'ai donnée, par évenement me semble la plus simple, si ton affichage est de type SWING/JAVAFX/SWT, où dans l'évenement, il suffit d'avoir la référence du composant d'affichage (par exemple, un JTable), et de lancer un rafraichissement (en lançant un runnable dans le thread graphique - nous préciser ton type d'interface, pour qu'on te donne le détail sur la méthode à utiliser).
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 List<Future> futures = new ArrayList<>(); for(int i=1; i<nbreTotalPage+1; i++){ EntrepriseWorkerTask uneTask = new EntrepriseWorkerTask("iteration " +i ,esClient,requetePoste, mRequestProperties, i, pageSize,path,lstItem,nbreTotalPage); futures.add( executorPool.submit(uneTask) ); // on stocke le résultat d'éxécution dans une liste } int nbTacheExectuees=0; for (Future<?> future : futures) { // on parcourt toutes les tâches try { future.get(); // attend que la tâche soit terminée pour répondre nbTacheExectuees++; System.out.println("Tâches exécutées : " + nbTacheExectuees); } catch (InterruptedException e) { throw new RuntimeException(e); } catch (ExecutionException e) { // ici traitement particulier à faire pour gérer le fait qu'il y a une erreur pendant l'exécution de la tâche // throw new RuntimeException(e); } } System.out.println("Toutes les tâches sont terminées"); ...
PS : ça me semble bizarre de donner un tel travail à un débutant sans un minimum de prise en charge (de guide) par un développeur confirmé.
L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
Nouveau sur le forum ? Consultez Les Règles du Club.
Merci beaucoup!
Ces quelques lignes m'ont grandement appris!
Donc en effet c'est SWING que j'utilise avec une interface web de l'autre coter.
En effet je suis d'accord que c'est plutôt compliqué pour mon niveau (Bac+3 en alternance) mais ils n'ont hélas pas de développeur spécialisé dans angular, etc et ce que je reprend à été réalisé par un ancien prestataire...
Je souffre mais j'apprend beaucoup également!
Euh, je ne comprends pas : c'est une application avec une interface Web ou avec une interface Swing ? Parce que si c'est une application avec une interface Web, et que tu affiches tes tâches avec une UI Swing, soit tu l'exécutes sur le serveur, dans une session ouverte, ce qui n'est pas obligatoire, sans parler du fait qu'un serveur n'a pas forcément d'écran, soit tu l'exécutes sur un client distant, et il va te falloir, en plus de gérer la mise à jour de l'affichage, soit faire du push, ce qui n'est pas forcément accessible à un débutant, à mon avis, soit du polling, ce qui risque d'être peu efficace sauf en cas de traitement vraiment très long (si tu demandes toutes les minutes les tâches terminées et que tout se fait en 20 secondes, il n'y a aucun intérêt à faire tout çà : autant afficher directement le résultat quand tout est terminé).
L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
Nouveau sur le forum ? Consultez Les Règles du Club.
Partager