[Java] Thread, TableModel et conception

Thread, TableModel et conception [Java] - Java - Programmation

Marsh Posté le 04-09-2004 à 15:28:21    

Bonjour,
j'ai un souci au niveau de la conception de mes classes :
 
j'ai plusieurs TableModel qui implémentent la meme interface de calcul et  
plusieurs instances d'une JTable qui ont ces TableModel pour model.
 
Le calcul pouvant etre long, je passe le TableModel en argument à une classe dérivée de Thread et j'exécute la méthode de calcul dans le run de ce thread, comme ça :
 

Code :
  1. public CombiThread(JTable aTable, TableModel aCombi)
  2. {
  3.       this.table = aTable;
  4.       this.combi = aCombi;
  5. }
  6. public void run()
  7. {
  8.    ((ICalcul)combi).calculCombi(nMinimum);
  9.    table.setModel(new SortTableModel(combi));
  10. /* peux pas faire while (!interrupted())
  11.                          {
  12.                             calcul élémentaire1;
  13.                             calcul élémentaire2;
  14.                             etc...;
  15.                          }
  16. car la méthode calculCombi appelle des méthodes de calcul l'une après l'autre
  17. */

}
Mon problème est de pouvoir arreter le thread quand je veux, comment je pourrais faire avec la conception actuelle de mes classes ?

Reply

Marsh Posté le 04-09-2004 à 15:28:21   

Reply

Marsh Posté le 04-09-2004 à 18:48:32    

Je suis pas sur d'avoir bien compris ta question, mais tel que je vois le problème, c'est ta méthode calculCombi qui est l'opération longue ; c'est donc l'execution de cette méthode que tu dois interrompre, et c'est donc dans cette méthode que tu devrais placer la condition d'arrêt. Ou alors il va falloir revoir ta conception. Ou alors j'ai pas compris.


---------------
Au royaume des sourds, les borgnes sont sourds.
Reply

Marsh Posté le 04-09-2004 à 19:00:51    

en fait (sous réserve que j'ai bien compris), ce serait plus logique que ton interface ICalcul hérite de Runnable, et que la méthode calculCombi soit la méthode run de ce Runnable.


---------------
Au royaume des sourds, les borgnes sont sourds.
Reply

Marsh Posté le 05-09-2004 à 00:21:14    

En fait, je vais mettre tout mon code de calcul dans un thread, et je passerai le résultat du calcul à mon model, ce sera plus simple... par contre, si quelqu'un a une idée de la manière de remettre à zéro un tableau multidimensionnel sans parcourir tout le tableau, je suis intéressé.

Reply

Marsh Posté le 06-09-2004 à 12:06:09    

FortunateSon a écrit :

En fait, je vais mettre tout mon code de calcul dans un thread, et je passerai le résultat du calcul à mon model, ce sera plus simple... par contre, si quelqu'un a une idée de la manière de remettre à zéro un tableau multidimensionnel sans parcourir tout le tableau, je suis intéressé.


 
Dans ta classe de thread tu mets un booleen et dans ta méthode de calcul tu testes régulièrement sa valeur : s'il est à false ta méthode de calcul continue, sinon elle s'arrête d'elle-même de calculer.
Pour changer la valeur du boolean, tu mets des accesseurs synchronized sur  
la classe de thread.
 
ex:

Code :
  1. public class MonThread extends Thread
  2. {
  3. protected boolean shouldStop = false;
  4. public void run()
  5. {
  6. while(!this.shouldStop)
  7. {
  8. // calcul
  9. }
  10. }
  11. public void synchronized setShouldStop(boolean stop)
  12. {
  13. synchronized(this){
  14. this.shouldStop = stop;
  15. }
  16. }
  17. }


Reply

Marsh Posté le 06-09-2004 à 12:07:26    

pascal34 a écrit :

Dans ta classe de thread tu mets un booleen et dans ta méthode de calcul tu testes régulièrement sa valeur : s'il est à false ta méthode de calcul continue, sinon elle s'arrête d'elle-même de calculer.
Pour changer la valeur du boolean, tu mets des accesseurs synchronized sur  
la classe de thread.
 
ex:

Code :
  1. public class MonThread extends Thread
  2. {
  3.   protected boolean shouldStop = false;
  4.   public void run()
  5.   {
  6.     while(!this.shouldStop)
  7.     {
  8.       // calcul
  9.     }
  10.   }
  11.   public void synchronized setShouldStop(boolean stop)
  12.   {
  13.     synchronized(this)
  14.     {
  15.       this.shouldStop = stop;
  16.     }
  17.   }
  18. }




 
 
Désolé j'ai merdoyé  :D


Message édité par pascal34 le 06-09-2004 à 12:08:02
Reply

Marsh Posté le 06-09-2004 à 12:14:42    

je vois pas l'intérêt de sycnhroniser l'affectation du booléen. Pour un booléen, l'affectation est une opération atomique => y a pas de risque d'accès concurent.
 
même si dans une logique de calcul paralèlle, ce serait effectivement normal de synchroniser l'accès à cette ressource partagée. :jap: (mais dans ce cas, la lecture aussi)


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 06-09-2004 à 12:25:33    

benou a écrit :

je vois pas l'intérêt de sycnhroniser l'affectation du booléen. Pour un booléen, l'affectation est une opération atomique => y a pas de risque d'accès concurent.
 
même si dans une logique de calcul paralèlle, ce serait effectivement normal de synchroniser l'accès à cette ressource partagée. :jap: (mais dans ce cas, la lecture aussi)

c'est aussi que la méthode etant synchronized, rajouter un bloc synchronized dedans c'est peut-être superflu, ou il y a une bonne raison que j'ignore ?


---------------
Au royaume des sourds, les borgnes sont sourds.
Reply

Marsh Posté le 06-09-2004 à 12:29:03    

R3g a écrit :

c'est aussi que la méthode etant synchronized, rajouter un bloc synchronized dedans c'est peut-être superflu, ou il y a une bonne raison que j'ignore ?


j'avais pas vu ca.  :sweat:  
 
non, c'est un doublon inutile ...


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 06-09-2004 à 14:51:22    

Autant pour moi

Reply

Marsh Posté le 06-09-2004 à 14:51:22   

Reply

Marsh Posté le 06-09-2004 à 15:20:51    

En fait, je ne rajouterai aucun booléan supplémentaire car je vais mettre ce code de calcul dans un thread, et dans la boucle de calcul je vérifierai s'il a été interrompu tout simplement du genre :

Code :
  1. public void run()
  2. {
  3.   while (!interrupted() && blabla)
  4.   {
  5.     blablabla
  6.   }
  7. }


 
Par contre, quelqu'un aurait-il une astuce pour remettre à zéro un tableau multidimensionnel de manière efficace ? (cad sans parcourir tout le tableau pour remettre tous les éléments à zéro, sinon je préfère encore instancier un nv tableau ...)

Reply

Marsh Posté le 06-09-2004 à 15:27:10    

FortunateSon a écrit :

En fait, je ne rajouterai aucun booléan supplémentaire car je vais mettre ce code de calcul dans un thread, et dans la boucle de calcul je vérifierai s'il a été interrompu tout simplement du genre :

Code :
  1. public void run()
  2. {
  3.   while (!interrupted() && blabla)
  4.   {
  5.     blablabla
  6.   }
  7. }


 
Par contre, quelqu'un aurait-il une astuce pour remettre à zéro un tableau multidimensionnel de manière efficace ? (cad sans parcourir tout le tableau pour remettre tous les éléments à zéro, sinon je préfère encore instancier un nv tableau ...)

Non, c'est pas la même chose. Si tu veux pouvoir arrêter un thread proprement, mieux vaut mettre un flag booleen que tu verifie régulièrement.


---------------
Au royaume des sourds, les borgnes sont sourds.
Reply

Marsh Posté le 06-09-2004 à 15:47:21    

pour ton init de tableau, tu peux utiliser la méthode fill de java.util.Arrays


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 06-09-2004 à 16:03:54    

benou a écrit :

pour ton init de tableau, tu peux utiliser la méthode fill de java.util.Arrays


 
lol donnes moi un exemple stp.

Code :
  1. // tab initialisé
  2. byte[35][42][50][70][12] tab = ...


 
comment fais-tu pour remettre tous les éléments de ce tableau sans le parcourir en entier ?

Reply

Marsh Posté le 06-09-2004 à 16:05:03    

R3g a écrit :

Non, c'est pas la même chose. Si tu veux pouvoir arrêter un thread proprement, mieux vaut mettre un flag booleen que tu verifie régulièrement.


 
Justement, ce flag existe dans la classe de Thread et est là pour ça

Reply

Marsh Posté le 06-09-2004 à 16:09:51    

FortunateSon a écrit :

lol donnes moi un exemple stp.

lol va lire la doc stp.


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 06-09-2004 à 16:14:33    

FortunateSon a écrit :

lol donnes moi un exemple stp.

Code :
  1. // tab initialisé
  2. byte[35][42][50][70][12] tab = ...


 
comment fais-tu pour remettre tous les éléments de ce tableau sans le parcourir en entier ?


mon truc ca marche pour les tableaux à une dimensions.
 
Là, faut que tu boucles ...


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 06-09-2004 à 16:28:09    

Euh tu fais une array à 6 dimensions ou bien tu as pas capté la syntaxe? [:wam]


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 06-09-2004 à 16:28:52    

(sinon avec le Arrays.fill doit y'avoir moyen de faire joujou et limiter les boucles avec ça
http://java.sun.com/j2se/1.4.2/doc [...] ang.Object[],%20java.lang.Object)
mais bon sur 6 dimensions :sleep:)


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 06-09-2004 à 16:30:47    

the real moins moins a écrit :

sinon avec le Arrays.fill doit y'avoir moyen de faire joujou et limiter les boucles avec ça
http://java.sun.com/j2se/1.4.2/doc [...] ang.Object[],%20java.lang.Object)


et tu fais ca comment ?


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 06-09-2004 à 16:47:23    

the real moins moins a écrit :

lol va lire la doc stp.


 
qui t'a dit que je n'ai pas lu la doc ?
 
La doc elle dit quoi sur les tableau multidimensionnels ?
Toi qui as l'air de bien la connaitre, donnes moi un exemple stp ...

Reply

Marsh Posté le 06-09-2004 à 16:51:48    

the real moins moins a écrit :

Euh tu fais une array à 6 dimensions ou bien tu as pas capté la syntaxe? [:wam]


C'est une array à 5 dimensions ...
 
Celles que j'utilise en réalité c'est plutot :

Code :
  1. byte[n][n-1][n-2][n-3][n-4] tab;


et chacun des sous-tableaux contient d'autres tableaux de dimension n-1 et ainsi de suite ...
 
je n'utilise pas de List ou autre, mais uniquement des tableaux de byte pour une question de mémoire ...

Reply

Marsh Posté le 06-09-2004 à 17:22:19    

pour gagner encore en mémoire tu peux aplatir ton tableau multi-dimmensionnel en un tableau à 1 dimension :  

Code :
  1. // byte[n][n-1][n-2][n-3][n-4] tab;
  2. byte[n * (n-1) * (n-2) * (n-3) * (n-4)] tab;
  3. // byte b = tab[2][4][1][0][6];
  4. byte b = tab[2 + 4*(n-1) + 1*(n-2) + 0*(n-3) + 6*(n-4)];


après faut faire gaffe que l'indice ne dépasse pas la capacité d'un int ...


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 06-09-2004 à 17:30:21    

benou a écrit :

pour gagner encore en mémoire tu peux aplatir ton tableau multi-dimmensionnel en un tableau à 1 dimension :  

Code :
  1. // byte[n][n-1][n-2][n-3][n-4] tab;
  2. byte[n * (n-1) * (n-2) * (n-3) * (n-4)] tab;
  3. // byte b = tab[2][4][1][0][6];
  4. byte b = tab[2 + 4*(n-1) + 1*(n-2) + 0*(n-3) + 6*(n-4)];


après faut faire gaffe que l'indice ne dépasse pas la capacité d'un int ...


 
J'y ai pensé mais le calcul pour trouver l'indice est plus compliqué que ça et prend plus de temps que pour l'utilisation du tableau à n dimensions (par contre, c'est vrai que ça prend beaucoup moins en mémoire).
Le calcul que tu proposes n'est pas bon car en fait, les sous-tableaux sont des tableaux à n dimensions aussi (de longueur n-1 dans chacun des sous-tableaux) !
 
Edit : dans mon cas, aplatir le tableau en un seul revient à passer de 40Mo à 12Mo environ mais le calcul est plus complexe et plus long


Message édité par fortunateson le 06-09-2004 à 17:32:36
Reply

Marsh Posté le 06-09-2004 à 17:58:50    

oauis, j'ai oublié quelques parenthèses  :whistle:  
 
enfin, t'as compris ce que je voulais dire ...
ca fait vraiment une grosse différence de temps d'accès aux données ?? ca m'étonne un peu ...
dans quel rapport ?


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 06-09-2004 à 18:02:20    

benou a écrit :

et tu fais ca comment ?


euh ouais euh.. faudrait reussir à recuperer une des dimensions du tableau en fait :gratgrat:
 
euh sinon FortunateSon, tu fais quoi avec des tableaux de 5 dims? [:wam]


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 06-09-2004 à 18:03:25    

FortunateSon a écrit :

qui t'a dit que je n'ai pas lu la doc ?
 
La doc elle dit quoi sur les tableau multidimensionnels ?

elle dit que la méthode fill de Arrays travaille sur une dimension [:itm]


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 06-09-2004 à 18:50:52    

benou a écrit :

oauis, j'ai oublié quelques parenthèses  :whistle:  
 
enfin, t'as compris ce que je voulais dire ...
ca fait vraiment une grosse différence de temps d'accès aux données ?? ca m'étonne un peu ...
dans quel rapport ?


 
Sur ce tableau, j'ai pas vraiment essayé mais sur un tableau de type byte[][][] donc à "3" dimensions seulement, le temps est triplé quasiment --> j'ai pas essayé plus loin.

Reply

Marsh Posté le 06-09-2004 à 19:01:12    

the real moins moins a écrit :

euh ouais euh.. faudrait reussir à recuperer une des dimensions du tableau en fait :gratgrat:
 
euh sinon FortunateSon, tu fais quoi avec des tableaux de 5 dims? [:wam]


 
En vérité, ce n'est même pas un tableau de 5 dimensions mais de 5 éléments de n dimensions (j'avais un peu simplifié + haut pour etre plus clair) et n > (10*5) :-)
 
Edit : vous comprenez pourquoi ça doit etre fait dans un thread maintenant ? ;-)


Message édité par fortunateson le 06-09-2004 à 19:03:12
Reply

Marsh Posté le 06-09-2004 à 20:24:50    

Citation :

(20:22) nraynaud: au fait, tu dira à Benou que dans un bloc synchronized, y'a une "write barrier" à la sortie et que donc changement atomique ou pas, la sémantique avec ou sans bloc est pas la même et qu'il pourrait avoir des surprises sur des architectures un peu "éclatées"


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 06-09-2004 à 20:43:49    

tu diras à nraynaud que si il veut expliqué un peu plus en détail je suis intéressé (parce que là j'ai pas bien capté ...)


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 06-09-2004 à 20:48:07    

eat this:

Citation :

(20:27) nraynaud: en fait, java a le droit de changer l'ordre des instructions
 
 
mais il faut faire gaffe parce que quand tu es en multithread, tu peux avoir des surprises
 
donc y'a des points qui sont safe à certains points de vue
 
et la fin d'un bloc synchronized est safe (mais je sais plsu jusqu'où s'étend la sécurité, uniquement les "transient" ? les transients qui ont été touchées dans le bloc ? toutes les variables touchées dans le bloc ? toutes les variables touchées avant le bloc ?)
 
c'est à cause de ce désorde d'exécution que le double checked locking ne marche pas en java.
 
(enfin dans les implémentations habituelles il marche, mais dans la sepc il marche pas)
 
c'est clair ?
 
(20:44) nraynaud: Any association between locks and variables is purely conventional. Locking any lock conceptually flushes all variables from a thread's working memory, and unlocking any lock forces the writing out to main memory of all variables that the thread has assigned.
 
 
JLS 17.9 (parce que la spec formelle est imbitable et qu'il y a un JSR pour tenter de la modifier)


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 06-09-2004 à 20:58:06    

je comprend bien le problème qui se pose si y a un changement d'ordre des instructions l'ordre d'un double-check, mais je vois pas le problème qui pourrait se poser lors d'une opération atomique du type affectation. je vois pas l'influence que ca peut avoir sur un autre thread ...


---------------
ma vie, mon oeuvre - HomePlayer
Reply

Marsh Posté le 06-09-2004 à 21:11:22    

Citation :


nraynaud (09:10 PM) :  
en fait tant que le thread qui a fait l'affectation ne passe pas une "write barrier", les autres threads ne voient pas la modif (dans le pire cas) et ça peut être long d'en rencontrer une (par rapport à l'échelle de temps de l'appli)



---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 06-09-2004 à 21:12:56    

Citation :


nraynaud (09:11 PM) :  
c'est clair au moins ?
nraynaud (09:12 PM) :  
et l'entrée et la sortie des blocs de synchro sont des write barrier


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 06-09-2004 à 21:30:16    

Citation :


nraynaud (09:27 PM) :  
pour benou >  
j'adore le mec qui pose une question, ne se fait pas se faire comprendre, et se fout de la gueule de celui qui lui demande une précision pour l'aider.
 
C'est un comportement digne d'un boulet catégorie poid lourd.
 
je t'envoie donc te faire foutre en bonne et dûe forme  :hello:
 


Message édité par Harkonnen le 06-09-2004 à 21:31:27

---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 06-09-2004 à 22:15:55    

[:rofl]

Reply

Marsh Posté le 06-09-2004 à 22:49:25    

[:rofl2]


---------------
Just because you feel good does not make you right
Reply

Marsh Posté le 06-09-2004 à 23:58:29    

c'est des cours par correspondance et par personnes interposées ?

Reply

Marsh Posté le 07-09-2004 à 08:28:51    

FortunateSon a écrit :

Justement, ce flag existe dans la classe de Thread et est là pour ça

Ah ok, autant pour moi, j'avais jamais vu [:mlc]
 
sinon nraynaud il est ban pour poster par correspondance comme ça ?


---------------
Au royaume des sourds, les borgnes sont sourds.
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed