Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2024 connectés 

 


 Mot :   Pseudo :  
 
 Page :   1  2  3
Auteur Sujet :

multithread

n°613920
benou
Posté le 16-01-2004 à 21:38:13  profilanswer
 

Reprise du message précédent :

nraynaud a écrit :

tu laisses mourrir ton thread et tu en recrées un autre ? (dans le catch tu recrées le nouveau thread, tu règles tout au niveau du pool et tu relances l'exception).


et c'est quoi l'intérêt ?????
 

nraynaud a écrit :


Les debuggeurs s'arrêtent au point de départ de l'exception et ça permet de debugger. Sinon c'est comme swing : la merde à debugger (à coup de breakpoints dans Throwable()). Car si on bouffe l'exception, on n'a qu'une trace dans la sortie standard, un peu mince comme indice du problème.


??? mais ca reviendrait exactement au même que je laisse passer l'exception ... je comprend pas ce que tu veux dire ... En quoi le debuggueur se comporterait différement ?
 
si le mec veut intercepter les erreur, il peut le faire au niveau du traitement ... Quand n runnable plante, si tu laisse passer l'exception à traers le run, tu n'as plus aucun contrôle ... Donc je vois pas en quoi c'est gênent que moi je la catche après [:spamafote]
 

nraynaud a écrit :


Aussi j'aurais fait une création lazy (au besoin) des threads.


ouais, c'est ce que je disais quand je parlais d'une dynamisation du pool de thread. En même temps là, tu gagne en perf : les threads sont créés à l'initialisation => le pool est plus réactif ... Tu penses que ca vouffe bcp de ressource un thread en pause ?
 

nraynaud a écrit :


Et puis mettre un close() finalize c'est une connerie, à cause du pointeur vers l'objet englobant.


?? hein ?
c'est dans le finalize du pool qu'il faut mettre le close, pas dans les Pooled Thread.


---------------
ma vie, mon oeuvre - HomePlayer
mood
Publicité
Posté le 16-01-2004 à 21:38:13  profilanswer
 

n°614022
nraynaud
lol
Posté le 16-01-2004 à 23:19:31  profilanswer
 

benou a écrit :

ouais, c'est ce que je disais quand je parlais d'une dynamisation du pool de thread. En même temps là, tu gagne en perf : les threads sont créés à l'initialisation => le pool est plus réactif ... Tu penses que ca vouffe bcp de ressource un thread en pause ?
 
 
?? hein ?
c'est dans le finalize du pool qu'il faut mettre le close, pas dans les Pooled Thread.

(j'ai la flemme d'expliquer le coup du débuggeur)
1) oui, car le nombre final de threads est (devrait-être) en relation avec la capacité de la machine, au niveau scheduler, context-switch et tout le boxon. D'autre part ça 'lisse' un peu le débit d'allocation dans le temps.
 
2) je parle du champ ThreadPool2.this dans les instances de PooledThread. Tant qu'il reste une seule instance de PooledThread non-collectable dans le système, le pool n'est pas collectable.
Hors les threads bloqués ne sont pas collectables (à ma connaissance, il faudrait vérifier, mais je sais pas si c'est dans la spec de la JVM ou du langage).


---------------
trainoo.com, c'est fini
n°614058
benou
Posté le 16-01-2004 à 23:43:54  profilanswer
 

nraynaud a écrit :

2) je parle du champ ThreadPool2.this dans les instances de PooledThread. Tant qu'il reste une seule instance de PooledThread non-collectable dans le système, le pool n'est pas collectable.
Hors les threads bloqués ne sont pas collectables (à ma connaissance, il faudrait vérifier, mais je sais pas si c'est dans la spec de la JVM ou du langage).


ben dans le close() de ThreadPool je finalise les threads : il se terminent. Ensuite ils vont se faire garbage collecté avec le ThreadPool ...


Message édité par benou le 16-01-2004 à 23:44:13

---------------
ma vie, mon oeuvre - HomePlayer
n°614071
nraynaud
lol
Posté le 16-01-2004 à 23:51:40  profilanswer
 

benou a écrit :


ben dans le close() de ThreadPool je finalise les threads : il se terminent. Ensuite ils vont se faire garbage collecté avec le ThreadPool ...

Je parlais de ma lumineuse idée de finalize() faudrait suivre un peu.
 
C'est bien, je fais un poste et après il faut que je me justifie sur 4 pages. Je pense que je vais arrêter de poster tout court.


---------------
trainoo.com, c'est fini
n°614088
torpe23
Posté le 17-01-2004 à 00:05:24  profilanswer
 

Eh moi, j'ai un autre problème!  
Je crée mon thread. Je le lances mais j'ai fait un bouton "Abort" qui est censé me permettre d'arrêter le thread. Dans le "actionPerformed", j'appelle donc la méthode "interrupt()" u thread, mais ce con, il continue à tourner en arrière plan. Comment ça se fait?

n°614104
benou
Posté le 17-01-2004 à 00:15:35  profilanswer
 

nraynaud a écrit :

Je parlais de ma lumineuse idée de finalize() faudrait suivre un peu.


ben oui et moi je parlais de mettre close() dans finalize()  
 

nraynaud a écrit :


C'est bien, je fais un poste et après il faut que je me justifie sur 4 pages. Je pense que je vais arrêter de poster tout court.


Bienvenue tu es sur un form. Ca sert à discuter [:dawa]
 
 
 
[:kiki]


Message édité par benou le 17-01-2004 à 00:15:45

---------------
ma vie, mon oeuvre - HomePlayer
n°614117
benou
Posté le 17-01-2004 à 00:21:00  profilanswer
 

torpe23 a écrit :

Eh moi, j'ai un autre problème!  
Je crée mon thread. Je le lances mais j'ai fait un bouton "Abort" qui est censé me permettre d'arrêter le thread. Dans le "actionPerformed", j'appelle donc la méthode "interrupt()" u thread, mais ce con, il continue à tourner en arrière plan. Comment ça se fait?


Ben c'est quoi la condition d'arrêt de la boucle de ton thread ? si ca vérifie pas que le thread a été intérompu, c'est normal que le thread s'arrête pas. Un interrupt sur le thread ca le fait sortir de pause du style wait() ou Thread.sleep(), mais ca le fait pas "arrêter son execution". C'était ce que faisait la méthode stop() de Thread mais c'était tellement désastreux (que deviennent les traitement en cours ??? comment les arrêter proprement)  que cette méthode a été dépréciée.
 
Donc c'est à toi de faire s'arrêter le thread en sortant de la méthode run.
Pour la boucle de ton thread, tu peux utiliser ca comme condition (si tu est dans un Runnable) :
while(! Thread.currentThread().isInterrupted()) { ... }
 
ou si l'objet en question EST UN thread, tu peux juste faire  
while (! this.isInterrupted()) { ... }


---------------
ma vie, mon oeuvre - HomePlayer
n°614127
torpe23
Posté le 17-01-2004 à 00:22:48  profilanswer
 

Ok merci! Je pensais effectivement que "interrupt" marchait comme "stop"!

n°614130
nraynaud
lol
Posté le 17-01-2004 à 00:23:14  profilanswer
 

benou a écrit :


ben oui et moi je parlais de mettre close() dans finalize()  

donc tu n'as pas compris.  
Le threadpool n'est pas collectable car reste des threads non collectables. Donc finalize (du pool) n'est pas appellé. Mais c'est lui qui doit rendre les threads collectables. Il faut donc explicitement appeller le close. Le close dans le finalize est d'ailleur une double connerie : en dehors du fait que ça ne fonctionne pas. Appeller explicitement close() (ce qui est la chose à faire) va rendre le pool éventuellement collectable. plus tard le pool devient collectable, on le finalize et là c'est le drame, close a déjà été appellée.
 
Conclusion : si vous voulez des mauvaises idées incompréhensibles, appellez-moi.


---------------
trainoo.com, c'est fini
n°614140
torpe23
Posté le 17-01-2004 à 00:26:25  profilanswer
 

C'est cool, ça marche maintenant! merci bcp!

mood
Publicité
Posté le 17-01-2004 à 00:26:25  profilanswer
 

n°614147
benou
Posté le 17-01-2004 à 00:36:26  profilanswer
 

nraynaud a écrit :

donc tu n'as pas compris.  


En effet tu as raison.
 
Mais bon c'était pas parce que y avait close dans finalize que fallait pas l'appeler explicitement. Mais c'est vrai que ca servait à rien de le mettre.
 
Et puis le fait d'appeler 2 fois close n'est pas gênant ... Et même si ca plantait, il me semble que les exceptions générés dans un finalize sont ignorées...


---------------
ma vie, mon oeuvre - HomePlayer
n°614150
nraynaud
lol
Posté le 17-01-2004 à 00:39:02  profilanswer
 

benou a écrit :


Et puis le fait d'appeler 2 fois close n'est pas gênant ... Et même si ca plantait, il me semble que les exceptions générés dans un finalize sont ignorées...

Elles le sont, j'ai lu ça dans le JLS récement.


---------------
trainoo.com, c'est fini
n°614210
the real m​oins moins
Posté le 17-01-2004 à 01:18:52  profilanswer
 

nraynaud a écrit :

Elles le sont, j'ai lu ça dans le JLS récement.

euh vous dites ça en general ou bien dans le cadre des threads? et ça ne concerne que les runtime alors? ?? ????


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
n°614265
benou
Posté le 17-01-2004 à 05:52:14  profilanswer
 

the real moins moins a écrit :

euh vous dites ça en general ou bien dans le cadre des threads? et ça ne concerne que les runtime alors? ?? ????


en générale.
 
Les runtime et les Error : les autres exceptions c'est pas possible : la signature de finalize n'a pas de close throws


---------------
ma vie, mon oeuvre - HomePlayer
n°614266
the real m​oins moins
Posté le 17-01-2004 à 06:01:04  profilanswer
 

uh putain j'avais finally en tete, c'est pour ça que gt tout étonné. j'ai rien dit
 
 
va dormir :heink:


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
n°614268
benou
Posté le 17-01-2004 à 06:02:40  profilanswer
 


nan mais là ma nuit est finie :/
 
mais j'y retournerai bien [:sisicaivrai]


---------------
ma vie, mon oeuvre - HomePlayer
n°614270
benou
Posté le 17-01-2004 à 06:03:17  profilanswer
 

et qu'est ce que tu fais encore là toi ? [:w3c compliant]


---------------
ma vie, mon oeuvre - HomePlayer
n°614272
the real m​oins moins
Posté le 17-01-2004 à 06:04:15  profilanswer
 

[:w3c compliant] comme tu dis :/
rentré *tard* du boulot et j'avais envie de commencer un projet en rentrant.
et merde, 6h30..tain..


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
n°614274
benou
Posté le 17-01-2004 à 06:07:03  profilanswer
 

the real moins moins a écrit :


et merde, 6h30..tain..


ben ouais, quand même quoi .... :/


---------------
ma vie, mon oeuvre - HomePlayer
n°615648
BifaceMcLe​OD
The HighGlandeur
Posté le 19-01-2004 à 14:23:38  profilanswer
 

benou a écrit :


Ben c'est quoi la condition d'arrêt de la boucle de ton thread ? si ca vérifie pas que le thread a été intérompu, c'est normal que le thread s'arrête pas. Un interrupt sur le thread ca le fait sortir de pause du style wait() ou Thread.sleep(), mais ca le fait pas "arrêter son execution". C'était ce que faisait la méthode stop() de Thread mais c'était tellement désastreux (que deviennent les traitement en cours ??? comment les arrêter proprement)  que cette méthode a été dépréciée.
 
Donc c'est à toi de faire s'arrêter le thread en sortant de la méthode run.
Pour la boucle de ton thread, tu peux utiliser ca comme condition (si tu est dans un Runnable) :
while(! Thread.currentThread().isInterrupted()) { ... }
 
ou si l'objet en question EST UN thread, tu peux juste faire  
while (! this.isInterrupted()) { ... }


La plupart du temps, il suffit de faire :

Code :
  1. try {
  2.   ... // le code
  3. }
  4. catch (InterruptedException e) {
  5.   ... // Thread.interrupt() a été appelé sur le thread.
  6. }


 
Le problème, c'est que 99 fois sur 100, les programmeurs ignorent magistralement les InterruptedException, avec un catch vide ou équivalent. Problème auquel n'échappe d'ailleurs pas le pool de threads de benou...  :(

n°619486
krosso
j'suis à la bourre
Posté le 22-01-2004 à 22:32:08  profilanswer
 

benou a écrit :


ca faisait un moment que ca me démangeait de coder ca :D
 
quand j'aurais du courage je ferai la version qui augmente son pool de thread dynamiquement ;)


 
Benou, je te remercie à nouveau et garde ta solution sous le coude.
Finalement je m'en suis tenu aux appels à isAlive(). Ca fonctionne très bien.
 
K.

n°621074
benou
Posté le 24-01-2004 à 22:53:32  profilanswer
 

BifaceMcLeOD a écrit :


Problème auquel n'échappe d'ailleurs pas le pool de threads de benou...  :(


 :heink:


---------------
ma vie, mon oeuvre - HomePlayer
n°621803
BifaceMcLe​OD
The HighGlandeur
Posté le 26-01-2004 à 12:59:21  profilanswer
 

Code :
  1. ...
  2. public void run() {
  3.   while (! mustStop) {
  4.     try {
  5.       synchronized (this) {
  6.         this.work = null;
  7.         synchronized(ThreadPool2.this.readyThreads) {
  8.           //notify the pool that the thread is ready  
  9.           ThreadPool2.this.readyThreads.push(this);
  10.           ThreadPool2.this.readyThreads.notify();
  11.         }
  12.         this.wait();
  13.       }
  14.     } catch (InterruptedException e) {
  15.       continue;
  16.     }
  17.     if (this.work != null) {
  18.       try {
  19.         this.work.run();
  20.       } catch (Throwable t) {
  21.         t.printStackTrace();
  22.       }
  23.       Thread.interrupted(); // clear the interrupt status  
  24.     }
  25.   }
  26. }


A ma connaissance, ce n'est pas parce qu'on sort du wait() qu'une InterruptedException est levée (on est sans doute d'accord, mais ça va toujours mieux en le disant ; je le dis quand même parce que je ne vois pas trop à quoi sert le "Thread.interrupted()" ).
InterruptedException n'est levée que si Thread.interrupt() est exécutée sur le thread pendant qu'il est au milieu du wait(). Dès lors, l'instruction exécutée ici est un continue, le thread va repartir au début de la boucle et se remettre en attente. En d'autres termes, l'interruption est ignorée. Non ?


Message édité par BifaceMcLeOD le 26-01-2004 à 12:59:39
n°621983
benou
Posté le 26-01-2004 à 15:57:09  profilanswer
 

le Thread.interrupted() sert justement remettre le statut d'interuption du thread à false. C'est un des effets de bord de méthode (regarde la javadoc) que je trouve très mal nommée...  
 

BifaceMcLeOD a écrit :

Dès lors, l'instruction exécutée ici est un continue, le thread va repartir au début de la boucle et se remettre en attente. En d'autres termes, l'interruption est ignorée. Non ?


oui.
 
En fait, au moment où tu fais le wait(), le thread est "libre" => seul le pool devrait avoir une référence vers le thread => recevoir une interruption à ce moment est plutot inhabituel. Ca ne devrait se produire que quand le pool est fermé, pas lorsqu'une tache est executée. Quand le pool se ferme, on appelle d'abord end() (qui met le booléen d'arrêt de la boucle à false) puis on fait un interrupt. Le traiteemnt de l'interruption fais continue => on fait le test de la boucle qui est faux => le thread se termine.
Par contre si une tache avait garéd une référence sur le thread et fait un interrupt après sa terminaison, le fait de faire un continue ne terminera pas le thread, ce qui est le but.
 
Donc, je ne pense pas que la façon dont je gère les interruption soit bancale ... ou en tout cas j'ai pas compris en quoi elle l'était [:spamafote]


---------------
ma vie, mon oeuvre - HomePlayer
n°622675
BifaceMcLe​OD
The HighGlandeur
Posté le 27-01-2004 à 12:09:53  profilanswer
 

benou a écrit :

le Thread.interrupted() sert justement remettre le statut d'interuption du thread à false. C'est un des effets de bord de méthode (regarde la javadoc) que je trouve très mal nommée...  
 
(...)
 
oui.
 
En fait, au moment où tu fais le wait(), le thread est "libre" => seul le pool devrait avoir une référence vers le thread => recevoir une interruption à ce moment est plutot inhabituel. Ca ne devrait se produire que quand le pool est fermé, pas lorsqu'une tache est executée. Quand le pool se ferme, on appelle d'abord end() (qui met le booléen d'arrêt de la boucle à false) puis on fait un interrupt. Le traitement de l'interruption fais continue => on fait le test de la boucle qui est faux => le thread se termine.
Par contre si une tache avait garéd une référence sur le thread et fait un interrupt après sa terminaison, le fait de faire un continue ne terminera pas le thread, ce qui est le but.
 
Donc, je ne pense pas que la façon dont je gère les interruption soit bancale ... ou en tout cas j'ai pas compris en quoi elle l'était [:spamafote]


J'avais compris à quoi sert, dans le principe, Thread.interrupted() (le petit commentaire qui accompagne son appel est parfaitement approprié :jap: ) , mais d'après le code, pour moi, elle n'est jamais appelée quand il faut. Soit InterruptedException est levée, et this.work est null ; dans ce cas, appeler Thread.interrupted() est sans effet, et puis de toute façon le continue dans le catch saute le bloc où se trouve l'appel à Thread.interrupted(), donc l'instruction est inutile dans ce cas. L'autre cas de figure, c'est quand this.work est non nul, mais dans ce cas, InterruptedException n'a pas été levée, donc il n'y a pas de statut d'interruption du thread à remettre à false. Donc l'appel à Thread.interrupted() n'est pas utile non plus.
Ou alors j'ai loupé quelque chose ?
 
A mon avis, le code suivant, plus simple, doit être meilleur :

Code :
  1. ...
  2. public void run() { 
  3. try
  4.    while (! mustStop) { 
  5.      synchronized (this) { 
  6.        this.work = null; 
  7.        synchronized(ThreadPool2.this.readyThreads) { 
  8.          //notify the pool that the thread is ready   
  9.          ThreadPool2.this.readyThreads.push(this); 
  10.          ThreadPool2.this.readyThreads.notify(); 
  11.        } 
  12.        this.wait(); 
  13.      }
  14.    } 
  15.    if (this.work != null) { 
  16.      try
  17.        this.work.run(); 
  18.      } catch (Throwable t) { 
  19.        t.printStackTrace(); 
  20.      } 
  21.    } 
  22. } catch (InterruptedException e) { 
  23.    // Interruption du thread
  24.    // => on le fait mourir de sa belle mort.
  25. }   
  26. }


Message édité par BifaceMcLeOD le 27-01-2004 à 12:11:17
n°622699
BifaceMcLe​OD
The HighGlandeur
Posté le 27-01-2004 à 12:26:05  profilanswer
 

Au passage, il n'y a pas besoin de maintenir une liste ou une pile de threads du pool disponibles. La méthode Object.wait() en maintient une implicitement. Il suffit juste, dans le code du pool, de maintenir un compteur indiquant le nombre de threads disponibles, que l'on incrémente juste avant le wait de chaque thread et que l'on décrémente juste en sortie du wait().
 
Autre indicateur utile dans le pool : un compteur supplémentaire qui indique le nombre de threads effectivement lancés. Cela permet d'éviter de lancer tous les threads d'un seul coup au démarrage du pool (plus économe en mémoire et en temps CPU), et plutôt de ne les lancer que lorsque tous les threads déjà lancés sont occupés mais qu'on n'a pas encore atteint le taille max du pool. Ce compteur permet même (étape suivante) de faire gonfler/dégonfler le pool de threads à la demande. Mais là, on est déjà dans la haute couture... :D

n°622780
benou
Posté le 27-01-2004 à 13:29:40  profilanswer
 

BifaceMcLeOD a écrit :

A mon avis, le code suivant, plus simple, doit être meilleur :[/cpp]


ben non ...
dans le cas où c'est le work (la tache à effectuer) qui déclenche la InterruptedException, tu te retrouves avec un Thread qui est dans l'état intérompu mais qui continue à tourner ... c'est justement l'intérêt du interrupted() : remettre le thread en non-intérompu pour le cas où ils l'aurait été
 
Sans dire que dans ce cas là tu vas printstacktracer la InterruptedException, ce qui est plutot bizarre ...
 

Citation :

Au passage, il n'y a pas besoin de maintenir une liste ou une pile de threads du pool disponibles. La méthode Object.wait() en maintient une implicitement. Il suffit juste, dans le code du pool, de maintenir un compteur indiquant le nombre de threads disponibles, que l'on incrémente juste avant le wait de chaque thread et que l'on décrémente juste en sortie du wait().  


et comment on retrouve le thread libre quand on en recherche un ??  
C'est justement l'intérêt de la pile : éviter de devoir parcourir le tableau de thread. (ce que je faisais dans la 1ere version du pool)
 
 

Citation :

[...] Mais là, on est déjà dans la haute couture... :D


Si t'avais tout lu, j'ai déjà dit qu'on pourrait faire ca. Mais le but c'était de torcher un truc vite fait à la base :o
 
Si tu veux coder la version dynamique du pool, vas-y :)
 
et puis bon, si on a besoin d'un truc évolué, autant utiliser un pool de thread déjà tout fait ...


Message édité par benou le 27-01-2004 à 13:30:56

---------------
ma vie, mon oeuvre - HomePlayer
n°622812
BifaceMcLe​OD
The HighGlandeur
Posté le 27-01-2004 à 13:48:57  profilanswer
 

benou a écrit :


ben non ...
dans le cas où c'est le work (la tache à effectuer) qui déclenche la InterruptedException, tu te retrouves avec un Thread qui est dans l'état intérompu mais qui continue à tourner ... c'est justement l'intérêt du interrupted() : remettre le thread en non-intérompu pour le cas où ils l'aurait été
 
Sans dire que dans ce cas là tu vas printstacktracer la InterruptedException, ce qui est plutot bizarre ...


C'est juste, je n'avais pas pensé au cas où c'est l'objet Runnable qui lève InterruptedException. Et je suis d'accord, faire un printStackTrace de l'InterruptedException, c'est un peu bizarre. Mais dans ton code, c'est ce qui est fait de toute façon, non ?
 
Pour la nécessité de l'appel à Thread.interrupted(), du coup, je suis convaincu.
 

Citation :

et comment on retrouve le thread libre quand on en recherche un ??  
C'est justement l'intérêt de la pile : éviter de devoir parcourir le tableau de thread. (ce que je faisais dans la 1ere version du pool)


Pourquoi as-tu besoin de rechercher un thread libre ? C'est déjà ce que fait le wait(). Quand n threads sont en wait() sur le même objet, et qu'un notify() est fait sur cet objet, la JVM choisit au hasard l'un des threads en wait et le réveille, les autres restants en wait(). Donc la recherche est faite par la JVM, tu n'as jamais besoin de la faire toi-même.
De toute façon, soit les threads sont en wait(), soit ils sont au milieu d'un Runnable.run() (les autres instructions étant négligeables). Donc ceux qui sont "libres" sont tous ceux en wait(). Ceux-là même que le wait() liste implicitement.
 
Le seul cas, éventuellement, où tu pourrais avoir besoin de parcourir les threads, est lorsque tu veux leur donner le même ordre à tous (exemple, pour que chacun se termine). Et là encore, tu peux te débrouiller autrement. Par exemple, il suffit que le "mustStop" soit un attribut du pool et non du thread, et tu fais autant de notify() sur l'objet "lock" (du pool) que tu as démarré de threads.


Message édité par BifaceMcLeOD le 27-01-2004 à 14:10:59
n°623211
benou
Posté le 27-01-2004 à 22:56:07  profilanswer
 

BifaceMcLeOD a écrit :


Mais dans ton code, c'est ce qui est fait de toute façon, non ?


ha oui tiens  :whistle:  
 

BifaceMcLeOD a écrit :

Pourquoi as-tu besoin de rechercher un thread libre ? C'est déjà ce que fait le wait(). Quand n threads sont en wait() sur le même objet, et qu'un notify() est fait sur cet objet, la JVM choisit au hasard l'un des threads en wait et le réveille, les autres restants en wait(). Donc la recherche est faite par la JVM, tu n'as jamais besoin de la faire toi-même.
De toute façon, soit les threads sont en wait(), soit ils sont au milieu d'un Runnable.run() (les autres instructions étant négligeables). Donc ceux qui sont "libres" sont tous ceux en wait(). Ceux-là même que le wait() liste implicitement.
 
Le seul cas, éventuellement, où tu pourrais avoir besoin de parcourir les threads, est lorsque tu veux leur donner le même ordre à tous (exemple, pour que chacun se termine). Et là encore, tu peux te débrouiller autrement. Par exemple, il suffit que le "mustStop" soit un attribut du pool et non du thread, et tu fais autant de notify() sur l'objet "lock" (du pool) que tu as démarré de threads.


je suis d'accord que tu n'as pas besoin de pile pour faire que les threads se réveille, mais si tu ne fais pas de pile et que tu ne "sélectionnes" pas le thread, que tu le laisse se réveiller tout seul par un notify, comment tu fais pour lui fournir l'objet Runnable à executer ?.
 
Sinon, ok pour la remarque sur le mustStop qui pourrait être dans le pool au lieu d'être dans chaque thread. En même temps, j'aime bien l'idée de pouvoir controller l'arrêt de chaque thread indépendemment ...


Message édité par benou le 27-01-2004 à 22:56:38

---------------
ma vie, mon oeuvre - HomePlayer
n°623901
BifaceMcLe​OD
The HighGlandeur
Posté le 28-01-2004 à 15:30:58  profilanswer
 

benou a écrit :


je suis d'accord que tu n'as pas besoin de pile pour faire que les threads se réveille, mais si tu ne fais pas de pile et que tu ne "sélectionnes" pas le thread, que tu le laisse se réveiller tout seul par un notify, comment tu fais pour lui fournir l'objet Runnable à executer ?.


De la même manière que tout le reste : le Runnable à démarrer peut être stocké dans un attribut du pool. Et les threads du pool peuvent lire cet attribut sans danger, car tous les accès à cet objet se font à l'intérieur d'un bloc "synchronized(myPool.lock)"
 

Citation :

Sinon, ok pour la remarque sur le mustStop qui pourrait être dans le pool au lieu d'être dans chaque thread. En même temps, j'aime bien l'idée de pouvoir controller l'arrêt de chaque thread indépendemment ...


Contrôler l'arrêt de chaque thread indépendamment des autres ne nécessite pas de nommer les threads. Je veux dire : ce n'est pas parce que le pool n'a pas de référence explicite sur ses 10 threads qu'il ne peut pas arrêter un (et un seul) de ses 10 threads. C'est une question d'organisation.  ;)  
 
Et puis ça a un autre avantage que le pool ne connaisse pas ses threads, notamment dans le cas d'un pool dynamique : ça évite les références circulaires entre le pool et les threads, ce qui facilite le boulot du garbage collector.
 
Mais entre nous, je te comprends. Moi aussi, quand j'ai commencé à bosser sur les problématiques de pools de threads Java, ça me posait un problème que le pool ne connaisse pas ses threads. Et il m'a fallu pas mal de temps (et d'exécutions de test) pour accepter que finalement, le pool pouvait marcher aussi bien sans connaître ses threads.


Message édité par BifaceMcLeOD le 28-01-2004 à 15:35:31
n°623970
nraynaud
lol
Posté le 28-01-2004 à 16:06:15  profilanswer
 

BifaceMcLeOD a écrit :

ça évite les références circulaires entre le pool et les threads, ce qui facilite le boulot du garbage collector.

Le GC il s'en branle complet des références circulaires. Ou encore mieux : pour le même nombre de références dans le système, plus il y a de références circulaires et moins il y a d'objets à parcourir.


---------------
trainoo.com, c'est fini
n°623992
BifaceMcLe​OD
The HighGlandeur
Posté le 28-01-2004 à 16:23:31  profilanswer
 

Ici, le choix, c'est entre avoir une liste de références ou ne pas avoir de références du tout. Et moins il y a de références, mieux on se porte, non ?

n°624000
benou
Posté le 28-01-2004 à 16:35:41  profilanswer
 

BifaceMcLeOD a écrit :


De la même manière que tout le reste : le Runnable à démarrer peut être stocké dans un attribut du pool. Et les threads du pool peuvent lire cet attribut sans danger, car tous les accès à cet objet se font à l'intérieur d'un bloc "synchronized(myPool.lock)"


en effet :jap:
 

BifaceMcLeOD a écrit :

Contrôler l'arrêt de chaque thread indépendamment des autres ne nécessite pas de nommer les threads. Je veux dire : ce n'est pas parce que le pool n'a pas de référence explicite sur ses 10 threads qu'il ne peut pas arrêter un (et un seul) de ses 10 threads...


 :heink:  
ben si tu ne peux pas appeler inetrrupt sur les threads, comment tu les arrêtes quand ils sont en attente ?


---------------
ma vie, mon oeuvre - HomePlayer
n°624004
nraynaud
lol
Posté le 28-01-2004 à 16:41:00  profilanswer
 

BifaceMcLeOD a écrit :

Ici, le choix, c'est entre avoir une liste de références ou ne pas avoir de références du tout. Et moins il y a de références, mieux on se porte, non ?

oui, mais rien à voir avec le GC, on veut moins de bordel pour consomer moins de mémoire et avoir des invariants plus simples.
 
Par contre j'ai pas compris, le coup d'arrêter ou de démarrer les threads sans avoir de références dessus. Tu peux expliquer pour quelqu'un qui ne sait rien faire à part un bloc synchronized stp ?


---------------
trainoo.com, c'est fini
n°624700
BifaceMcLe​OD
The HighGlandeur
Posté le 29-01-2004 à 11:42:46  profilanswer
 

Pour être sûr qu'on parle de la même chose, nraynaud, je me permets de préciser les termes : je ne parle pas de démarrer ou arrêter les threads (au sens créer/détruire), mais de les endormir et de les réveiller.  
 
Or ces 2 dernières opérations se font par de simples  myPool.lock.wait() et myPool.lock.notify(). C'est justement la spécification de ces 2 méthodes : si n threads on tfait un wait() sur un objet dit de synchronisation (le fameux attribut "lock" du pool), ils deviennt endormis, jusqu'à ce qu'un notify() sur l'objet de synchronisation soit fait. Et par spécification, cet appel à notify() va réveiller un de ces threads endormis. Il est impossible de prédire à l'avance lequel des threads endormis sera réveillé (là encore, par spécification du notify()), mais on a la garantie qu'un et un seul d'entre eux sera réveillé. Alors bien sûr, in fine, une liste des threads endormis sur l'objet de synchronisation existe. Mais le programmeur n'a pas à la maintenir, c'est l'implémentation de la méthode Object.wait() qui la maintient automatiquement.
 
Par contre, il est clair que le pool de threads doit quand même savoir combien de threads il a lancés, et combien sont endormis à l'instant courant, s'il veut par exemple pouvoir tous les réveiller :

Code :
  1. while (this.numWaitingThreads > 0) {
  2.   this.lock.notify();
  3.   this.numWaitingThreads--;
  4. }


Pour le reste, c'est-à-dire la communication entre le pool et les threads, tout peut passer au travers d'attributs du pool, auxquels tous les threads du pool sont susceptibles d'accéder.

n°624709
nraynaud
lol
Posté le 29-01-2004 à 11:48:31  profilanswer
 

BifaceMcLeOD a écrit :

Or ces 2 dernières opérations se font par de simples  myPool.lock.wait() et myPool.lock.notify().

ok, merci.


---------------
trainoo.com, c'est fini
n°624722
benou
Posté le 29-01-2004 à 12:02:20  profilanswer
 

BifaceMcLeOD a écrit :

Pour le reste, c'est-à-dire la communication entre le pool et les threads, tout peut passer au travers d'attributs du pool, auxquels tous les threads du pool sont susceptibles d'accéder.


J'ai toujours pas compris comment tu comptes pouvoir arrêter tes threads sans faire de interrupt ... Si un des threads a fait un sleep(), la seule façon de l'arrêter c'est de l'intérompre et si tu as pas de référence dessus, tu peux pas [:spamafote]


---------------
ma vie, mon oeuvre - HomePlayer
n°674086
BifaceMcLe​OD
The HighGlandeur
Posté le 15-03-2004 à 14:36:26  profilanswer
 

Désolé, je n'avais pas vu que tu m'avais posé une question !  :o  
 
Très simple : tu les réveilles tous, après avoir positionné un booléen stopThreads dans le pool à true. La première chose qu'un thread du pool doit vérifier en sortant de son sommeil, c'est que ThreadPool.this.stopAllThreads est à false ; si ce booléen est à vrai, le thread meurt de sa belle mort, en sortant proprement de sa méthode run().
 
Tu vas me dire : comment faire pour réveiller tous les threads ? C'est facile dès que tu sais combien tu as de threads dans ton pool :

Code :
  1. class ThreadPool {
  2.   ...
  3.   void stopAllThreads() {
  4.     this.stopThreads = true;
  5.     while (this.numStartedThreads > 0) {
  6.       this.lock.notify();
  7.       this.numStartedThreads--;
  8.     }
  9.   }
  10.   ...
  11. }

n°674579
benou
Posté le 15-03-2004 à 21:49:48  profilanswer
 

je te parle d'intérompre (leThread.interrupt()), pas de réveiller. relis bien mon dernier post ...

n°674921
BifaceMcLe​OD
The HighGlandeur
Posté le 16-03-2004 à 12:17:46  profilanswer
 

J'ai bien lu : tu veux arrêter tous les threads. Soit tu les interromps tous (mais dans ce cas, il te faut une référence vers chacun des objets Thread), soit tu réveilles chacun d'entre eux après les avoir mis dans un état particulier qui les fera s'arrêter d'eux-mêmes immédiatement (dans ce cas, le notify() ne requiert pas de référence explicite sur les threads).

n°674988
benou
Posté le 16-03-2004 à 13:12:10  profilanswer
 

BifaceMcLeOD a écrit :

J'ai bien lu : tu veux arrêter tous les threads. Soit tu les interromps tous (mais dans ce cas, il te faut une référence vers chacun des objets Thread), soit tu réveilles chacun d'entre eux après les avoir mis dans un état particulier qui les fera s'arrêter d'eux-mêmes immédiatement (dans ce cas, le notify() ne requiert pas de référence explicite sur les threads).


ben oui mais quand tu fais un pool de thread, qur tu demandes au pool de s'arrêter, c'est normal d'arrêter les treads => faire un interrupt => il faut un référence vers chaque thread ...
 
Enfin, c'était intéressant comme discussion.
Quand j'aurais le temps et la motivation, j'essayerai de faire un pool de thread tiptop, qui grossit, se rétrécit, etc ...


---------------
ma vie, mon oeuvre - HomePlayer
mood
Publicité
Posté le   profilanswer
 

 Page :   1  2  3

Aller à :
Ajouter une réponse
 

Sujets relatifs
multithread , sémaphore, linux : endormir un thread.multithread ou pas?
client serveur multithreadMultithread sous VB 6 ?
[C]Multithread 
Plus de sujets relatifs à : multithread


Copyright © 1997-2025 Groupe LDLC (Signaler un contenu illicite / Données personnelles)