Thread java
Fermé
supcomingénieur
Messages postés
74
Date d'inscription
vendredi 10 février 2012
Statut
Membre
Dernière intervention
16 juillet 2013
-
8 avril 2013 à 12:22
KX Messages postés 16753 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 - 11 avril 2013 à 19:15
KX Messages postés 16753 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 25 novembre 2024 - 11 avril 2013 à 19:15
A voir également:
- Thread java
- Waptrick java football - Télécharger - Jeux vidéo
- Jeux java itel football - Télécharger - Jeux vidéo
- Java apk - Télécharger - Langages
- Java décompiler - Télécharger - Langages
- Jeux java itel touche - Forum Mobile
3 réponses
KX
Messages postés
16753
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
25 novembre 2024
3 020
8 avril 2013 à 18:39
8 avril 2013 à 18:39
"1. est ce qu'il faut que la classe devienne un thread pour pourvoir exploiter ses resultat au fur et à mesur?"
Pas forcément cette classe en particulier, mais il faudra qu'à un moment tu ais plusieurs fils d'exécution en parallèle, au minimum l'exécution qui fait les calculs et celle qui les utilise. Après que ce soit l'une ou l'autre qui soit un thread, ça dépend de ce que tu fais exactement.
"2. une variable de cette classe change de valeur pendant l'exécution, est ce que c'est possible de suivre cette variable et l'utiliser en parallèle par une autre classe java (a l'aide d'un getter par exemple)??"
Bien sûr c'est tout à fait possible, là encore ça va dépendre du genre de calculs que tu fais mais en général ça se fait bien, même s'il faut parfois prendre quelques précautions (pour les set en particulier)
Voici un exemple simple, je fais une boucle (qui fait varier n de start à end) et en parallèle toutes les secondes je regarde la valeur de n pour savoir à quel avancement on en est (pour savoir quand ça se termine)
Pas forcément cette classe en particulier, mais il faudra qu'à un moment tu ais plusieurs fils d'exécution en parallèle, au minimum l'exécution qui fait les calculs et celle qui les utilise. Après que ce soit l'une ou l'autre qui soit un thread, ça dépend de ce que tu fais exactement.
"2. une variable de cette classe change de valeur pendant l'exécution, est ce que c'est possible de suivre cette variable et l'utiliser en parallèle par une autre classe java (a l'aide d'un getter par exemple)??"
Bien sûr c'est tout à fait possible, là encore ça va dépendre du genre de calculs que tu fais mais en général ça se fait bien, même s'il faut parfois prendre quelques précautions (pour les set en particulier)
Voici un exemple simple, je fais une boucle (qui fait varier n de start à end) et en parallèle toutes les secondes je regarde la valeur de n pour savoir à quel avancement on en est (pour savoir quand ça se termine)
public class Test { private static int n; public static void main(String[] args) { final int start = 0; final int end = (int) 1e12; Thread t = new Thread() { @Override public void run() { while (true) { if (isInterrupted()) return; try { Thread.sleep(1000); } catch (InterruptedException e) { return; } System.out.printf("Avancement : %.2f %%\n",n*100.0/(end-start)); } } }; t.start(); for (n=start; n<=end; n++) { // ... } t.interrupt(); } }
supcomingénieur
Messages postés
74
Date d'inscription
vendredi 10 février 2012
Statut
Membre
Dernière intervention
16 juillet 2013
1
Modifié par supcomingénieur le 10/04/2013 à 09:38
Modifié par supcomingénieur le 10/04/2013 à 09:38
merci beacoup pour cette exemple!!
ton exemple prend une variable n de type entier et suit son évolution: comment faire avec une variable booléenne?? je m'explique:
j'ai une classe java appelée SNMP walk qui comme son nom l'indique effectue une requête snmp walk et retourne le resultat au fur et à mesure dans un fichier texte. le resultat est d'environ 400000 lignes (ce qui explique pourkoi j'ai opté pour un traitement en parallèle). j'ai une autre classe java qui prend ce fichier en entrée et met a jour une base de donnée sql en fonction des données qui se trouve dans le fichier. je voudrai moi faire l'algorithme suivant: laisse ma classe SNMP walk tourner toute seule en partageant l'écrirure entre deux fichiers (au llieu d'un), une fois elle ecrit 1000 lignes dans le premier puis 1000 lignes dans le dexième puis 1000 lignes dans le premier et ainsi de suite. parallèlement ma classe qui met a jour la base devrait detecter quel est le dernier fichier qui vient d'être rempli avec les 1000 nouvelles lignes et l'utilise dans son traitement et ainsi de suite jusqu'à ce que la requête se termine. pour ce faire j'ai besoin de deux variables : une booleenne qui indique qui indique quand la requête est terminée et une de type String qui donne le nom de fichier qui est prêt à être utilisé.
j'espère avoir été claire je sais que c'est compliqué. est ce que cet algorithme est faisable. merci bcp
ton exemple prend une variable n de type entier et suit son évolution: comment faire avec une variable booléenne?? je m'explique:
j'ai une classe java appelée SNMP walk qui comme son nom l'indique effectue une requête snmp walk et retourne le resultat au fur et à mesure dans un fichier texte. le resultat est d'environ 400000 lignes (ce qui explique pourkoi j'ai opté pour un traitement en parallèle). j'ai une autre classe java qui prend ce fichier en entrée et met a jour une base de donnée sql en fonction des données qui se trouve dans le fichier. je voudrai moi faire l'algorithme suivant: laisse ma classe SNMP walk tourner toute seule en partageant l'écrirure entre deux fichiers (au llieu d'un), une fois elle ecrit 1000 lignes dans le premier puis 1000 lignes dans le dexième puis 1000 lignes dans le premier et ainsi de suite. parallèlement ma classe qui met a jour la base devrait detecter quel est le dernier fichier qui vient d'être rempli avec les 1000 nouvelles lignes et l'utilise dans son traitement et ainsi de suite jusqu'à ce que la requête se termine. pour ce faire j'ai besoin de deux variables : une booleenne qui indique qui indique quand la requête est terminée et une de type String qui donne le nom de fichier qui est prêt à être utilisé.
j'espère avoir été claire je sais que c'est compliqué. est ce que cet algorithme est faisable. merci bcp
KX
Messages postés
16753
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
25 novembre 2024
3 020
10 avril 2013 à 18:48
10 avril 2013 à 18:48
Je ne comprends pas pourquoi tu passes par un fichier intermédiaire, bon éventuellement pour garder une trace de ce qui a été généré d'accord, mais une fois ta ligne générée tu pourrais t'en servir immédiatement sans avoir à attendre la fin du fichier...
Actuellement tu fais :
Algo 1 :
créer fichier
opération snmp walk (je ne sais pas ce que c'est, mais peu importe)
générer ligne de texte
écrire ligne de texte dans fichier
recommencer jusqu'à la fin
fermer fichier
ouvrir fichier
lire ligne de texte
traiter la ligne pour la mettre dans la bdd
recommencer jusqu'à la fin du fichier
Ce que tu pourrais (je pense) faire c'est :
Algo 2 :
créer fichier
opération snmp walk
générer ligne de texte
écrire ligne de texte dans fichier
traiter la ligne pour la mettre dans la bdd
recommencer jusqu'à la fin
fermer fichier
Ensuite, c'est vrai il y a parfois des temps d'attente entre chaque opérations, surtout vu qu'il y a des opérations d'entrée/sorties (écriture sur disque, accès à la bdd, accès au réseau), et il serait regrettable de cumuler les temps d'attente. Alors en faisant trois threads on pourrait avoir :
Algo 3.1
opération snmp walk
générer ligne de texte
ajouter ligne dans les files d'attente A et B
recommencer jusqu'à la fin
ajouter fin de file à A et B
Algo 3.2
créer fichier
lire une ligne dans la file d'attente A
écrire ligne de texte dans fichier
recommencer jusqu'à la fin de file A
fermer fichier
Algo 3.3
lire une ligne dans la file d'attente B
traiter la ligne pour la mettre dans la bdd
recommencer jusqu'à la fin de la file B
Ici les trois algorithmes s'exécuteront "en même temps" en profitant chacun des temps de latence des autres. Remarque : pour éviter un engorgement de la mémoire, il faut toujours que les threads qui vident les files soient plus prioritaires que les threads qui les remplit.
Alors bien sûr ça ne correspond pas vraiment à l'algo que tu avais imaginé, mais je pense que c'est ce qu'il y aurait de mieux vu ton problème...
Actuellement tu fais :
Algo 1 :
créer fichier
opération snmp walk (je ne sais pas ce que c'est, mais peu importe)
générer ligne de texte
écrire ligne de texte dans fichier
recommencer jusqu'à la fin
fermer fichier
ouvrir fichier
lire ligne de texte
traiter la ligne pour la mettre dans la bdd
recommencer jusqu'à la fin du fichier
Ce que tu pourrais (je pense) faire c'est :
Algo 2 :
créer fichier
opération snmp walk
générer ligne de texte
écrire ligne de texte dans fichier
traiter la ligne pour la mettre dans la bdd
recommencer jusqu'à la fin
fermer fichier
Ensuite, c'est vrai il y a parfois des temps d'attente entre chaque opérations, surtout vu qu'il y a des opérations d'entrée/sorties (écriture sur disque, accès à la bdd, accès au réseau), et il serait regrettable de cumuler les temps d'attente. Alors en faisant trois threads on pourrait avoir :
Algo 3.1
opération snmp walk
générer ligne de texte
ajouter ligne dans les files d'attente A et B
recommencer jusqu'à la fin
ajouter fin de file à A et B
Algo 3.2
créer fichier
lire une ligne dans la file d'attente A
écrire ligne de texte dans fichier
recommencer jusqu'à la fin de file A
fermer fichier
Algo 3.3
lire une ligne dans la file d'attente B
traiter la ligne pour la mettre dans la bdd
recommencer jusqu'à la fin de la file B
Ici les trois algorithmes s'exécuteront "en même temps" en profitant chacun des temps de latence des autres. Remarque : pour éviter un engorgement de la mémoire, il faut toujours que les threads qui vident les files soient plus prioritaires que les threads qui les remplit.
Alors bien sûr ça ne correspond pas vraiment à l'algo que tu avais imaginé, mais je pense que c'est ce qu'il y aurait de mieux vu ton problème...
supcomingénieur
Messages postés
74
Date d'inscription
vendredi 10 février 2012
Statut
Membre
Dernière intervention
16 juillet 2013
1
11 avril 2013 à 09:39
11 avril 2013 à 09:39
merci bcp ca me parait tres logique. la question est comment faire en sorte que les algo s'éxécutent en parallèles car une fois un thread lancé il ne s'arrête plus jusqu'à sa fin. j'ai beau essayé d'accéder a ses donnée pendant quil tourne mais c'est impossible. je crois qu'il faudrait l'arêter avec la methode wait, chose que je ne veux surtout pas faire car son temps d'exécution est déa trop long
KX
Messages postés
16753
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
25 novembre 2024
3 020
11 avril 2013 à 19:15
11 avril 2013 à 19:15
Déjà il faudrait utiliser la classe ConcurrentLinkedQueue pour faire le partage de données entre plusieurs Threads.
Ton programme principal serait donc quelque chose comme ça :
Ensuite, il faut trouver une astuce pour faire la différence entre une file vide parce que le premier thread ne l'a pas encore rempli, et une file vide parce que le dernier élément à lire a déjà été lu.
Pour ça je te propose quelque chose de simple, c'est d'ajouter un objet null.
Voici par exemple comment on pourrai faire l'algo 3.2
Quelques explications :
La lecture de la file se fait avec poll qui donne l'élément qui a été ajouté en premier par thread1. Si la liste est vide on attend 1 seconde (par exemple), afin de laisser travailler le thread1 pour qu'il ajoute des valeurs dans les files. Si par contre on obtient null cela indique que le thread1 a terminé son traitement et que l'on a vidé toute la file, on peut s'arrêter.
La gestion des isInterrupted et InterruptedException permet de terminer proprement le thread (fermer le fichier ici) au cas où on utilise un arrêt du traitement (avec la méthode interrupt())
La priorité est à MAX - 1 (par exemple) elle est supérieure à la priorité du thread1 (qui pourrait être MAX-2) car il est préférable d'aller plus vite à libérer la liste et avoir des listes vides de temps en temps et attendre un peu (pour autoriser les autres threads à travailler) que d'être toujours plus lent à vider la liste, d'accumuler du retard, et avoir une erreur mémoire car la file sera pleine.
Remarque : on gardera la priorité MAX pour un éventuel thread "d'urgence" qui utilisera des interrupt pour arrêter les threads (en cas d'exception par exemple).
Ton programme principal serait donc quelque chose comme ça :
// Opérations à faire avant ... // Création des files final ConcurrentLinkedQueue<String> fileA = new ConcurrentLinkedQueue<String>(); final ConcurrentLinkedQueue<String> fileB = new ConcurrentLinkedQueue<String>(); // Création des threads final Thread thread1 = new Algo1(fileA,fileB /* autres paramètres pour SNMP */); final Thread thread2 = new Algo2(fileA, String fileName); final Thread thread3 = new Algo3(fileB /* autres paramètres pour la BDD */); // Démarrage des threads en parallèle thread1.start(); thread2.start(); thread3.start(); // Attente de la fin des 3 threads thread1.join(); thread2.join(); thread3.join(); // Opérations à faire après ...
Ensuite, il faut trouver une astuce pour faire la différence entre une file vide parce que le premier thread ne l'a pas encore rempli, et une file vide parce que le dernier élément à lire a déjà été lu.
Pour ça je te propose quelque chose de simple, c'est d'ajouter un objet null.
Voici par exemple comment on pourrai faire l'algo 3.2
import java.io.FileWriter; import java.util.concurrent.ConcurrentLinkedQueue; public class Algo2 extends Thread { private final ConcurrentLinkedQueue<String> in; private final FileWriter out; public Algo2(final ConcurrentLinkedQueue<String> fileA, String fileName) { in = fileA; out = new FileWriter(fileName); setPriority(MAX_PRIORITY-1); } @Override public void run() { while (true) { if (isInterrupted()) break; if (in.isEmpty()) { try { out.flush(); Thread.sleep(1000); } catch (InterruptedException e) { break; } } else { String str = in.poll(); if (str==null) break; else out.write(str); } } out.close(); } }
Quelques explications :
La lecture de la file se fait avec poll qui donne l'élément qui a été ajouté en premier par thread1. Si la liste est vide on attend 1 seconde (par exemple), afin de laisser travailler le thread1 pour qu'il ajoute des valeurs dans les files. Si par contre on obtient null cela indique que le thread1 a terminé son traitement et que l'on a vidé toute la file, on peut s'arrêter.
La gestion des isInterrupted et InterruptedException permet de terminer proprement le thread (fermer le fichier ici) au cas où on utilise un arrêt du traitement (avec la méthode interrupt())
La priorité est à MAX - 1 (par exemple) elle est supérieure à la priorité du thread1 (qui pourrait être MAX-2) car il est préférable d'aller plus vite à libérer la liste et avoir des listes vides de temps en temps et attendre un peu (pour autoriser les autres threads à travailler) que d'être toujours plus lent à vider la liste, d'accumuler du retard, et avoir une erreur mémoire car la file sera pleine.
Remarque : on gardera la priorité MAX pour un éventuel thread "d'urgence" qui utilisera des interrupt pour arrêter les threads (en cas d'exception par exemple).