[Java] Multithreading et gestion des exceptions

Multithreading et gestion des exceptions [Java] - Java - Programmation

Marsh Posté le 25-07-2004 à 00:01:35    

Dans une application monothread, c'est un choix :
- soit je catch
- soit je throw
 
En multithread, comment notifier la parent du thread que celui-ci a eu un problème ?

Reply

Marsh Posté le 25-07-2004 à 00:01:35   

Reply

Marsh Posté le 25-07-2004 à 00:20:55    

- y'a des handlers d'exception au niveau groupe de threads (et tout thread appartient par défaut au même groupe que son créateur, ce qui permet au passage de mettre un handler au thread de répartition des évènements swing, l'élite mondiale du java le sait bien).
- un catchall dans le run() (qui peut par exemple enfiler un évènement représentant l'erreur dans une file destinée au parent).

Reply

Marsh Posté le 25-07-2004 à 00:33:09    

Je vais commencer par lire la doc de ThreadGroup.
 
Par contre, la file dont tu parles dans le deuxième cas, tu la ferais comment ? Une pile, avec un listener qui scrute son contenu ?
 
EDIT : je sens que je vais m'amuser à synchroniser mes merdes.


Message édité par Cherrytree le 25-07-2004 à 00:35:26
Reply

Marsh Posté le 25-07-2004 à 00:41:35    

perso, l'implémentation la plus simple des files de messages est que je conaisse une LinkedList avec un wrapper synchronized.
tu pousses avec addLast() tu tires avec removeFirst().
 
bien entendu, c'est plus compliqué si le consomateur doit être réveillé au poussage (qu'il est pas en polling), mais des histoires de producteurs/consomateurs, y'en a plein les cours d'algo.

Reply

Marsh Posté le 25-07-2004 à 00:42:53    

on peut voir un peu le contexte ?

Reply

Marsh Posté le 25-07-2004 à 01:15:06    

Je programme une petite appli perso pour gérer les constituants d'un réseau.
 
J'utilise le stack SNMP de Westhawk et je tente de l'intégrer dans un module "collecte des informations".
 
Parmi les infos que je récupère, il y a par exemple, dans le cas d'un PC, l'utilisation mémoire de chaque processus soumis à l'OS.
 
Ce que j'ai fait :
Mon Main lance une tâche périodique de récupération de la mémoire utilisée. Celle-ci repose sur java.util.TimerTask et  permet de lancer le processus de collecte sur un objet dédié au parcours de tables administrables par SNMP (la mémoire figure dans une table). J'ai appelé cet objet un TableDataRetriever.
 
Le TDR est susceptible de lancer une exception lorsque la création du contexte SNMP échoue et lorsque l'envoi d'un paquet échoue.
 
De mon point de vue, ces problèmes doivent déclencher la destruction du contexte (peu ou prou une Socket), et l'annulation de la tâche périodique ou du timer.
 
Voilà. Tout commentaire (surtout s'il est verbeux) est le bienvenu.

Reply

Marsh Posté le 25-07-2004 à 01:16:18    

Je me rends compte que je suis incompréhensible. /o\

Reply

Marsh Posté le 25-07-2004 à 01:18:42    

Callback. Ton process est asynchrone. Donc si ton thread n'est pas capable de gérer l'erreur lui meme, il doit callbacker le "master", l'objet qui lui pourra le faire (ou joindre un composant capable de le faire)
 
Clairement tu passes une référence de callback à ton thread et tu l'utilises lorsqu'une exception doit etre remontée.


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

Marsh Posté le 25-07-2004 à 01:19:38    

nraynaud a écrit :

perso, l'implémentation la plus simple des files de messages est que je conaisse une LinkedList avec un wrapper synchronized.
tu pousses avec addLast() tu tires avec removeFirst().
 
bien entendu, c'est plus compliqué si le consomateur doit être réveillé au poussage (qu'il est pas en polling), mais des histoires de producteurs/consomateurs, y'en a plein les cours d'algo.


ça me dérange pas de mettre un thread en polling sur la file de message. J'ai juste un peu peur que ça devienne carrément ingérable quand je vais lancer des collectes sur plusieurs postes de données différentes par nature et type. Faut bien s'occuper.

Reply

Marsh Posté le 25-07-2004 à 01:24:29    

DarkLord a écrit :

Callback. Ton process est asynchrone. Donc si ton thread n'est pas capable de gérer l'erreur lui meme, il doit callbacker le "master", l'objet qui lui pourra le faire (ou joindre un composant capable de le faire)
 
Clairement tu passes une référence de callback à ton thread et tu l'utilises lorsqu'une exception doit etre remontée.


J'arrête pas de faire des callbacks avec ce stack ! /o\
 
Tiens d'ailleurs, il me semble que tu le connais ce stack, t'en penses quoi ?

Reply

Marsh Posté le 25-07-2004 à 01:24:29   

Reply

Marsh Posté le 25-07-2004 à 01:43:57    

cerisier > http://opensvn.csie.org/jcoincoin/ [...] ncoin/net/
 
le Networkscheduler (qui est un SINGLETON spécial --) reçoit des unités de travail (Task) et les exécute.
 
http://opensvn.csie.org/jcoincoin/ [...] ibune.java
Tribune.SenderTask est une tache qui envoie un OutputMessage sur le réseau.
Les OutputMessage sont listenable, et les listeners ont une callback et sont prévenus en cas d'exception lors de l'envoi du bouzin au serveur.
http://opensvn.csie.org/jcoincoin/ [...] ssage.java
 
ce qui fait donc que c'est à celui qui veut envoyer le message de se démerder avec ce qu'il veut faire de l'erreur.
 
le plopBot ne donne même pas de listener :
http://opensvn.csie.org/jcoincoin/ [...] opBot.java
 
l'interface graphique signale l'erreur et n'efface pas le message de la zone de saisie (chercher OutputMessage.Listener dans la page) :
http://opensvn.csie.org/jcoincoin/ [...] inGui.java
 
à noter que dans le dernier cas, le retour dans le thread de répartition des évènements swing se fait avec un SwingUtilities.invokeLater().

Reply

Marsh Posté le 25-07-2004 à 01:48:38    

nraynaud a écrit :


le Networkscheduler

:love:


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

Marsh Posté le 25-07-2004 à 02:50:20    

haben sie ein problem ?
 
 
edit : c'est le meilleur moyen que j'ai trouvé pour pas exploser la bande passante au démarrage et par la suite.


Message édité par nraynaud le 25-07-2004 à 02:51:07
Reply

Marsh Posté le 25-07-2004 à 08:51:12    

nraynaud a écrit :

cerisier > http://opensvn.csie.org/jcoincoin/ [...] ncoin/net/
 
le Networkscheduler (qui est un SINGLETON spécial --) reçoit des unités de travail (Task) et les exécute.
 
http://opensvn.csie.org/jcoincoin/ [...] ibune.java
Tribune.SenderTask est une tache qui envoie un OutputMessage sur le réseau.
Les OutputMessage sont listenable, et les listeners ont une callback et sont prévenus en cas d'exception lors de l'envoi du bouzin au serveur.
http://opensvn.csie.org/jcoincoin/ [...] ssage.java
 
ce qui fait donc que c'est à celui qui veut envoyer le message de se démerder avec ce qu'il veut faire de l'erreur.
 
le plopBot ne donne même pas de listener :
http://opensvn.csie.org/jcoincoin/ [...] opBot.java
 
l'interface graphique signale l'erreur et n'efface pas le message de la zone de saisie (chercher OutputMessage.Listener dans la page) :
http://opensvn.csie.org/jcoincoin/ [...] inGui.java
 
à noter que dans le dernier cas, le retour dans le thread de répartition des évènements swing se fait avec un SwingUtilities.invokeLater().


[:prosterne]


---------------
Le site de ma maman
Reply

Marsh Posté le 25-07-2004 à 13:31:45    


 
J'ai insisté là dessus qd j'ai envoyé son code au vendeur de pizza :o
C'est vrai, nraynaud, que c'est diablement bien implémenté ce truc :jap:


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

Marsh Posté le 25-07-2004 à 13:40:53    

Cherrytree a écrit :

J'arrête pas de faire des callbacks avec ce stack ! /o\
 
Tiens d'ailleurs, il me semble que tu le connais ce stack, t'en penses quoi ?


 
Je ne le connais pas, je l'ai référencé sur ce forum en cherchant bêtement sur google et parce qu'il me semblait être le meilleur choix à première vue.
 
Sinon pour le callback, tout dépend si tu veux gérer l'erreur de manière synchrone ou non.


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

Marsh Posté le 29-07-2004 à 09:47:09    

Je viens de passer un petit bout de temps à admirer la belle ouvrage mis en place dans NetworkScheduler et j'ai quelques questions sur les choix d'implémentation :
- Pourquoi ne pas avoir fait de Task un Runnable ? Ne serait-ce pas intéressant en place de work(), d'avoir un run(), qui permettrait d'utiliser l'objet Task hors du Scheduler, directement dans un bête Thread ?
- Je n'ai pas saisi la raison (car je sens qu'il y en a une) pour laquelle une PeriodicTask est une Task. Cela me semble lié au fait que tu confonds le membre Task et la PeriodicTask qui l'englobe (equals(), hashCode()), mais je ne vois pas le truc.
- Pourquoi le Timer est initialisé dans le constructeur de NetworkScheduler ? Tu sembles pourtant préférer l'initialisation des membres dès leur déclaration. ça porte un nom au fait, cette pratique qui consiste à initialiser au plus tôt, comme tu le fais ?
 
Je veux programmer comme toi. Que me conseilles-tu ?

Reply

Marsh Posté le 29-07-2004 à 12:25:19    

1) pour pas qu'un boulet me prenne un Task je ne sais où et le mette dans son thread. un Task, ça va dans un networkscheduler, pas ailleur.
2) on wrappe la Task, pour que à la fin de son traitement, elle se re-planifie toute seule.
 
3) ça a été modifié dans ma working-copy il y a une semaine, mais je peux pas comitter pour l'instant (because j'ai fait 15000 trucs dedans à la fois et y'en a un pas fini qui rend tout inutilisable).
 
4) avoir une vie de merde.


---------------
trainoo.com, c'est fini
Reply

Marsh Posté le 29-07-2004 à 13:46:45    

1) C'est un choix qui se défend.
2) Avec ton indication j'ai relu le source : c'est la clause finally de la méthode work() qui donne la solution.
3) OK, donc je vais avoir des choses passionnantes à découvrir. Ton commit est prévu pour quand ?
4) Moi j'trouve ça génial de coder si bien. J'suis sûr que ça peut servir [:itm]

Reply

Marsh Posté le 29-07-2004 à 13:56:44    

4) on peut pas dire que ça m'a beaucoup servi jusqu'à maintenant [:itm] Peut-être parce que les gens qui recrutent ne savent pas ce que c'est que du code.


---------------
trainoo.com, c'est fini
Reply

Marsh Posté le 29-07-2004 à 14:00:50    

nraynaud a écrit :

1) pour pas qu'un boulet me prenne un Task je ne sais où et le mette dans son thread. un Task, ça va dans un networkscheduler, pas ailleur.
2) on wrappe la Task, pour que à la fin de son traitement, elle se re-planifie toute seule.
 
3) ça a été modifié dans ma working-copy il y a une semaine, mais je peux pas comitter pour l'instant (because j'ai fait 15000 trucs dedans à la fois et y'en a un pas fini qui rend tout inutilisable).
 
4) avoir une vie de merde.


 
J'aime bien la facon dont tu ecris le code, c'est clair. J'essaie de faire comme ca mais je dérape des fois.
 
Sinon, je n'ai que rapidement parcouru les fichiers que tu cites, et je m'apercoit que je ne sais pas ce que fais ton appli (j'ai la fleme de lire le code et dechiffrer, j'ai cherché une page de description, mais j'ai pas trouvé :)). Tu mettras 2s a me le dire, là ou je mettrais 1h a lire :)
 
4) assez d'accord (je parle pour moi). Un jour, je fus comme ca :) j'ai arrété le jour où j'ai compris que ca ne m'apportait rien, si ce n'est la satisfaction d'avoir créé qqchose. Ce genre de travail est tres mal reconnu. En plus, les bugs, les gens pas contents de telle ou telle fonctionnalité manquante, ont finit par me bouffer tout mon temps libre et ont eu raison de ma volonté.
Maintenant, je ne code que pour le boulot => argent. C'est le seul interet que j'y trouve.

Reply

Marsh Posté le 29-07-2004 à 14:05:30    

nraynaud a écrit :

4) on peut pas dire que ça m'a beaucoup servi jusqu'à maintenant [:itm] Peut-être parce que les gens qui recrutent ne savent pas ce que c'est que du code.


 
4) et parce que n'importe qui peut marquer sur son CV : C#, C++, java, javaBeans, RMI, MFC, PHP, ASP, VB, Python, Perl ...
J'ai rencontré trop de cas comme ca : la dernière personne qui a repris un de mes softs  (prototype) au boulot, etait de ceux là. Incompétent en prog, il m'a ruiné le soft (ok, c'est pas facile de reprendre du code qu'on a pas écris) et maintenant le soft est abandonné (il y a plus de bugs qu'avant :() et ils en ont achèté un à l'extérieur...
(7 mois de boulot pour rien)

Reply

Marsh Posté le 29-07-2004 à 14:17:07    

nraynaud a écrit :

4) on peut pas dire que ça m'a beaucoup servi jusqu'à maintenant [:itm] Peut-être parce que les gens qui recrutent ne savent pas ce que c'est que du code.


 
Parce que les gens qui recrutent se fient plus à la première impression qu'au contenu du CV en général.


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

Marsh Posté le 29-07-2004 à 14:30:10    

DarkLord a écrit :

Parce que les gens qui recrutent se fient plus à la première impression qu'au contenu du CV en général.


N'empêche que du code comme ça, je n'en vois jamais. Je ne sais pas écrire comme ça. Et dans ma boite, ils parlent l'objet comme une vache espagnole.
 
Si ça existait, j'achèterais ce bouquin : "Programmer comme nraynaud pour les nuls".
 
EDIT : manquait un mot
 
Sinon nraynaud, y a quoi qui change dans le NetworkScheduler ? Je le trouve impec' comme ça ? Un petit teaser ? Et sinon, je pars en vacances dans 3 jours : tu me conseilles quoi comme saine lecture ?


Message édité par Cherrytree le 29-07-2004 à 15:00:21
Reply

Marsh Posté le 29-07-2004 à 15:03:11    

cherytree > uniquement le point que tu as soulevé je crois, c'est juste que je ne me suis mis il n'y a qu'une semaine ou 2 à vraiment tout mettre en instanciation lazy.
 
Je démarre éclipse, je fais un diff pour vérifier et je poste le code.


---------------
trainoo.com, c'est fini
Reply

Marsh Posté le 29-07-2004 à 15:08:59    

nraynaud a écrit :

1) cherytree > uniquement le point que tu as soulevé je crois, c'est juste que je ne me suis mis il n'y a qu'une semaine ou 2 à vraiment tout mettre en instanciation lazy.
 
2) Je démarre éclipse, je fais un diff pour vérifier et je poste le code.


1) C'est donc comme cela que ça s'appelle.
2) :jap:
 
Sinon, je ne sais pas si tu as la main dessus, mais http://opensvn.csie.org/ a l'air en rade. J'essayais de voir quelles classes implémentent Task... et paf.
 
Sinon concernant la litérature, tu ne peux rien m'apprendre ?

Reply

Marsh Posté le 29-07-2004 à 15:09:11    

-->je plussois : à quand un "Programmer comme nraynaud pur les nuls ?"


---------------
Jubi Photos : Flickr - 500px
Reply

Marsh Posté le 29-07-2004 à 15:13:34    

Si c'est moi qui l'écrit ça ira? [:itm]
(je lui ai tout appris [:spamafote])

Reply

Marsh Posté le 29-07-2004 à 15:14:27    

cerisier > oui, passé le timeout en macro, lazy instanciation du timer et du thread de pompage et un commentaire :

Code :
  1. /*
  2. * Created on 23 avr. 2004
  3. * This library is free software; you can redistribute it and/or
  4. * modify it under the terms of the GNU Library General Public
  5. * License as published by the Free Software Foundation; either
  6. * version 2 of the License, or (at your option) any later version.
  7. *
  8. * This library is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  11. * Library General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU Library General Public
  14. * License along with this library; if not, write to the
  15. * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  16. * Boston, MA 02111-1307, USA.
  17. */
  18. package jcoincoin.net;
  19. import java.util.HashMap;
  20. import java.util.HashSet;
  21. import java.util.LinkedList;
  22. import java.util.Map;
  23. import java.util.NoSuchElementException;
  24. import java.util.Set;
  25. import java.util.Timer;
  26. import java.util.TimerTask;
  27. /**
  28. * @author nraynaud
  29. *  
  30. * Represents a very simple time slicer. Using this avoid having lots of threads
  31. * in the system using the network randomly.
  32. *  
  33. * Units of work are represented by the Task interface. If the work takes more
  34. * than a certain amouth of time to complete, a second Thread is created to
  35. * continue fetching work out of the queue.
  36. *   
  37. */
  38. public class NetworkScheduler {
  39.     /**
  40.      * the time a task can run before we start a second thread to process the
  41.      * queue.
  42.      */
  43.     private static final int MAX_EXECUTION_TIME = 10000;
  44.     /**
  45.      * the great task queue
  46.      */
  47.     private LinkedList taskQueue = new LinkedList();
  48.     /**
  49.      * the big timer used for periodicity.
  50.      */
  51.     private Timer timer = null;
  52.     /**
  53.      * the hashmap Task -> PeriodicTask of the curently registered periodic
  54.      * tasks.
  55.      */
  56.     private final Map periodicTasksMap = new HashMap();
  57.     /**
  58.      * number of threads to process the task queue.
  59.      */
  60.     static private volatile int threadNumber = 0;
  61.     static private synchronized void incrementThreadnumber() {
  62.         threadNumber++;
  63.     }
  64.     static private synchronized void decrementThreadnumber() {
  65.         threadNumber--;
  66.     }
  67.     private Set executingTasks = new HashSet();
  68.     /**
  69.      * current main executor.
  70.      */
  71.     private Thread executor;
  72.     /**
  73.      * the big one scheduler
  74.      */
  75.     private static NetworkScheduler instance = null;
  76.     public static synchronized NetworkScheduler getInstance() {
  77.         if (instance == null)
  78.             instance = new NetworkScheduler();
  79.         return instance;
  80.     }
  81.     private NetworkScheduler() {
  82.     }
  83.     private void alertExecutor() {
  84.         assert (Thread.holdsLock(this));
  85.         if (executor == null)
  86.             executor = new WorkingThread();
  87.         synchronized (executor) {
  88.             executor.notify();
  89.         }
  90.     }
  91.     private synchronized Task getTask() {
  92.         try {
  93.             return (Task) taskQueue.removeFirst();
  94.         } catch (NoSuchElementException e) {
  95.             return null;
  96.         }
  97.     }
  98.     /**
  99.      * Immediately enqueue the given task for execution.
  100.      *  
  101.      * @param task
  102.      *            the task to enqueue.
  103.      */
  104.     public synchronized void enqueue(Task task) {
  105.         taskQueue.addLast(task);
  106.         alertExecutor();
  107.     }
  108.     /**
  109.      * Enqueue th task to be executed exactly at the end of the currently
  110.      * executing task. This means that unfair enqueuing are unfair betwen
  111.      * themselves too, this is not a priority scheme.
  112.      *  
  113.      * @param task
  114.      *            the work
  115.      */
  116.     public synchronized void unfairlyEnqueue(Task task) {
  117.         taskQueue.addFirst(task);
  118.         alertExecutor();
  119.     }
  120.     /**
  121.      * Schedules the given task to be enqueued regulary at the given period.
  122.      * Exactly, the task is sceduled to be reenqueued period millisecond after
  123.      * the end of it's execution. The task is first immediately enqueued.
  124.      *  
  125.      * @param task
  126.      *            the work unit.
  127.      * @param period
  128.      *            the period in milliseconds.
  129.      */
  130.     synchronized public void periodicalyEnqueue(final Task task,
  131.             final long period) {
  132.         PeriodicTask pTask = new PeriodicTask(task, period);
  133.         periodicTasksMap.put(task, pTask);
  134.         enqueue(pTask);
  135.     }
  136.     synchronized public void changePeriod(Task task, final long newPeriod) {
  137.         PeriodicTask pTask = (PeriodicTask) periodicTasksMap.get(task);
  138.         if (pTask == null)
  139.             throw new IllegalArgumentException(
  140.                     "the given task is not in the system" );
  141.         else
  142.             pTask.setPeriod(newPeriod);
  143.     }
  144.     synchronized public void removePeriodicTask(Task task) {
  145.         if (periodicTasksMap.remove(task) == null)
  146.             throw new IllegalArgumentException(
  147.                     "the given task is not in the system" );
  148.     }
  149.     /**
  150.      * Enqueues the given task after the given period.
  151.      *  
  152.      * @param task
  153.      *            the task to reenqueue
  154.      * @param delay
  155.      *            the delay to wait in milliseconds.
  156.      */
  157.     private void enqueueDelayed(final Task task, final long delay) {
  158.         getTimer().schedule(new TimerTask() {
  159.             public void run() {
  160.                 enqueue(task);
  161.             }
  162.         }, delay);
  163.     }
  164.     private synchronized Timer getTimer() {
  165.         if (timer == null)
  166.             timer = new Timer(true);
  167.         return timer;
  168.     }
  169.     /**
  170.      * Periodic Task proxy.
  171.      *  
  172.      *  
  173.      * @author nraynaud
  174.      *   
  175.      */
  176.     private class PeriodicTask implements Task {
  177.         private final Task task;
  178.         volatile private long period;
  179.         /**
  180.          * @param task
  181.          * @param period
  182.          */
  183.         public PeriodicTask(final Task task, long period) {
  184.             this.task = task;
  185.             this.period = period;
  186.         }
  187.         public void work() {
  188.             try {
  189.                 task.work();
  190.             } finally {
  191.                 synchronized (NetworkScheduler.this) {
  192.                     if (periodicTasksMap.get(task) == this)
  193.                         enqueueDelayed(this, period);
  194.                 }
  195.             }
  196.         }
  197.         public String toString() {
  198.             return task.toString() + " (made periodic)";
  199.         }
  200.         public void onException(Exception e) {
  201.             task.onException(e);
  202.         }
  203.         public boolean equals(Object other) {
  204.             return task.equals(other);
  205.         }
  206.         public int hashCode() {
  207.             return task.hashCode();
  208.         }
  209.         /**
  210.          * @return Returns the period.
  211.          */
  212.         synchronized public long getPeriod() {
  213.             return period;
  214.         }
  215.         /**
  216.          * @param period
  217.          *            The period to set.
  218.          */
  219.         synchronized public void setPeriod(long period) {
  220.             this.period = period;
  221.         }
  222.     }
  223.     /**
  224.      * @author nraynaud
  225.      *  
  226.      * get a task from the queue and execute it. If the task takes more than 15
  227.      * seconds to execute, a new thread is raised to flush-execute the task
  228.      * queue and this one is left to die.
  229.      */
  230.     private final class WorkingThread extends Thread {
  231.         private volatile boolean terminate = false;
  232.         private WorkingThread() {
  233.             super("network" );
  234.             this.setDaemon(true);
  235.             this.start();
  236.             incrementThreadnumber();
  237.             System.out.println("working threads : " + threadNumber);
  238.         }
  239.         /**
  240.          * blocks the thread until notified.
  241.          *   
  242.          */
  243.         private synchronized void waitForNotification() {
  244.             try {
  245.                 wait();
  246.             } catch (InterruptedException e) {
  247.                 //continue
  248.             }
  249.         }
  250.         public void run() {
  251.             while (!terminate) {
  252.                 Task task = getTask();
  253.                 if (task == null)
  254.                     waitForNotification();
  255.                 else if (!executingTasks.contains(task)) {
  256.                     executeTask(task);
  257.                 } else
  258.                     System.out.println("task :" + task + "already running" );
  259.             }
  260.             decrementThreadnumber();
  261.             System.out.println("working threads : " + threadNumber);
  262.         }
  263.         /**
  264.          * Executes the given task, using a timeout. If the time is over, a new
  265.          * executor is created to fetch the work queue.
  266.          */
  267.         private void executeTask(final Task task) {
  268.             TimerTask timeoutTask = new TimerTask() {
  269.                 public void run() {
  270.                     System.out.println("notice : task timeout : "
  271.                             + task.toString());
  272.                     terminate = true;
  273.                     assert (executor == WorkingThread.this);
  274.                     assert (task != null);
  275.                     executor = new WorkingThread();
  276.                 }
  277.             };
  278.             executingTasks.add(task);
  279.             getTimer().schedule(timeoutTask, MAX_EXECUTION_TIME);
  280.             try {
  281.                 task.work();
  282.             } catch (Exception e) {
  283.                 task.onException(e);
  284.             } finally {
  285.                 timeoutTask.cancel();
  286.                 executingTasks.remove(task);
  287.             }
  288.         }
  289.     }
  290. }


---------------
trainoo.com, c'est fini
Reply

Marsh Posté le 29-07-2004 à 15:14:31    

tu bluffes -- ...
 
--> je plussois la question : ca sert à quoi l'appli que tu fais nraynaud ?


---------------
Jubi Photos : Flickr - 500px
Reply

Marsh Posté le 29-07-2004 à 15:15:25    

hum, le quote s'est vautré, merci joce


---------------
Jubi Photos : Flickr - 500px
Reply

Marsh Posté le 29-07-2004 à 15:24:53    

c'est grace à -- que je suis dans l'élite mondiale du java ...
 
(par contre, moi je sais dans quel état se réveille un bean /o\)


---------------
trainoo.com, c'est fini
Reply

Marsh Posté le 29-07-2004 à 16:00:48    

[:rofl2]


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

Marsh Posté le 29-07-2004 à 16:06:09    

si tu l'avais sû, tu aurais peut-être pu lui expliquer toi-même [:itm]
 
(j'ai la ouache, ça doit être parce que l'ANPE vient de me refiler un contact douteux, alors j'exprime ma joie)


---------------
trainoo.com, c'est fini
Reply

Marsh Posté le 29-07-2004 à 16:09:01    

nraynaud a écrit :

si tu l'avais sû, tu aurais peut-être pu lui expliquer toi-même [:itm]


 
Je ne rigolais pas pour ça :heink:


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

Marsh Posté le 29-07-2004 à 16:14:11    

[:drapo]


---------------
IVG en france
Reply

Marsh Posté le 29-07-2004 à 16:19:21    

DarkLord a écrit :

Je ne rigolais pas pour ça :heink:

ça t'apprendra à faire une quote ?


---------------
trainoo.com, c'est fini
Reply

Marsh Posté le 29-07-2004 à 16:26:41    

nraynaud a écrit :

ça t'apprendra à faire une quote ?


 
non.
 

Citation :


c'est grace à -- que je suis dans l'élite mondiale du java ...  


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

Marsh Posté le 29-07-2004 à 16:52:34    

certain amouth of time to complete = certain amount of time to complete
 
(petite typo n<->h et invertion avec t)


---------------
Jubi Photos : Flickr - 500px
Reply

Marsh Posté le 29-07-2004 à 17:11:49    

Jubijub a écrit :

certain amouth of time to complete = certain amount of time to complete
 
(petite typo n<->h et invertion avec t)


Oui bon dans ce cas, on a aussi des curently, betwen, regulary, it's execution, et periodicaly (pas sûr mais presque que ça prend 2 'l's).

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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