Réponse acceptée !
Salut,
Swing et le multi-threading. Deux articles qui permettent de mieux comprendre ce sujet :
-
Threads et performance avec Swing-
SwingWorker (Java SE 6)Swing est un sous système de threads de la jvm. Ce sous système n'est pas thread safe, sauf pour quelques methodes : repaint(), invalidate() et revalidate() -
c'est à dire que la communication avec swing (l'invocation des méthodes swing) par des threads externes (ceux de la jvm) doit respecter un "contrat de communication" (une gestion des evenements centralisée par un seul thread qui est l'EDT). Le contrat est que toute communication avec l'interface doit se faire à travers les methodes invokeLater ou invokeAndWait de SwingUtilities. Ces méthodes sont chargées de créer un thread par message/evenement puis de placer ces threads dans la file d'attente de l'EDT, sans bloquer le thread qui les utilise (invokeLater) ou en mode bloquant (InvokeAndWait). Tout thread qui ne respecte pas ce contrat peut bloquer le système swing ou en etre exclu comme dans ton premier cas ou le thread JControler est créé dans un contexte externe à l'application swing (le thread de ton JControler, qu'il soit une extension de Thread ou une implémentation de Runnable, est créé dans la jvm et pas dans le sous système swing, parce qu'il n'est pas englobé dans un appel de type InvokeLater).
Une application swing est composé de trois threads :
- le main application thread qui execute le main()
- le toolkit thread qui est chargé de faire l'interface evenementielle (clic souris, clavier...) entre swing et l'os. Il envoi tous les messages à l'EDT :
- l'event dispatcher thread ou EDT qui est le coeur de swing. Il a la responsabilité de la gestion de la file d'attente des evenements swing et la distribution de ces evenements à chaque composant
Tout thread externe souhaitant communiquer avec le système swing doit passer par l'EDT.D'un autre côté, il est tout à fait possible d'envisager une application swing dont certains threads lancés depuis l'interface deviennent indépendants de l'EDT, parce ces threads réalisant des opérations lourdes pourraient bloquer l'EDT. Seulement, lorsque ces threads devenus indépendants veulent communiquer avec l'interface, il doivent à nouveau respecter le contrat (passer par l'EDT). Comme ils sont désynchronisés de l'EDT, ils doivent utiliser les methodes invokeLater ou invokeAndWait de SwingUtilities pour communiquer à nouveau avec lui (placer des messages dans sa file d'attente). Un mécanisme un peu plus perfectionné est celui des SwingWorker.
Faire une interface pour controler un seul thread ne me semble pas la meilleure solution (surtout si le programme principal est amené à lancer 50 threads, ca fait 50 interfaces...). Une seule interface pour controler plusieurs threads, du moment qu'ils respectent le contrat swing, est plus dans l'esprit de swing.