SWT et Mult-Threading

SWT et Mult-Threading - Java - Programmation

Marsh Posté le 26-01-2005 à 13:41:23    

Bonjour,
 
A la différence de Swing, SWT ne permet pas aux Threads différents de celui qui a créé l'interface graphique (user interface thread) de la modifier. Les actions à effectuer doivent se faire par l'intermédiaire des méthodes Display.syncExec(Runnable) et Display.asyncExec(Runnable).
 
Ce qui m'amène à me poser quelques questions surtout au niveau de l'architecture des programme (pour programmer propre et intelligement).
 
J'ai 2 Thread : le user interface et un autre qui bosse derrière mais qui doit modifier par brefs moments l'interface. Ce Thread ne peut éxécuter les méthdes syncExec et asyncExec (car mon appli a une interface swing et une swt, et que la classe du Thread est la meme pour les 2 versions, mais la n'est pas le problème). Ce Thread communique avec une classe (nommons la A) pour effectuer les changements. Cette classe A a été créée par le user inteface Thread et est accédé par les 2.
Je programme les appels aux méthodes comme ceci et je voulais savoir si c'était assez "propre" (ca ne me le semble pas) ou s'il y a une autre méthode de conception plus logique.
 

Code :
  1. class A {
  2.     public modifInterface() {
  3.         if(Display.getDefault().getThread() == Thread.currentThread())
  4.             realModif()
  5.         else Display.getDefault().syncExec(new Modifier());
  6.     }
  7.     private realModif() {
  8.         // code de modification
  9.     }
  10.     private class Modifier implements Runnable {
  11.          public void run() {
  12.              realModif();
  13.          }
  14.     }
  15. }



---------------
J.C. Farinet
Reply

Marsh Posté le 26-01-2005 à 13:41:23   

Reply

Marsh Posté le 26-01-2005 à 13:53:45    

yo c spi a écrit :

Bonjour,
 
A la différence de Swing, SWT ne permet pas aux Threads différents de celui qui a créé l'interface graphique (user interface thread) de la modifier. Les actions à effectuer doivent se faire par l'intermédiaire des méthodes Display.syncExec(Runnable) et Display.asyncExec(Runnable).


http://java.sun.com/products/jfc/t [...] eads1.html

Citation :

Once a Swing component has been realized, all code that might affect or depend on the state of that component should be executed in the event-dispatching thread.


 

Citation :

The SwingUtilities class provides two methods to help you run code in the event-dispatching thread:  
 
invokeLater(): Requests that some code be executed in the event-dispatching thread. This method returns immediately, without waiting for the code to execute.  
   
invokeAndWait(): Acts like invokeLater(), except that this method waits for the code to execute. As a rule, you should use invokeLater() instead of this method.  

Reply

Marsh Posté le 26-01-2005 à 14:38:14    

nraynaud, c'est les coups de pelle à clous pour avoir affirmé ce qu'il affirme dans sa premiere phrase, non?
(meme si c'est *faisable* c'est pas recommmandé quoi, ou je me trompe ?)


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

Marsh Posté le 26-01-2005 à 14:42:21    

c'est *pas* faisable.
 
y'a des fonctions qui sont isolées dans DefaultDocument, mais ça ne veut pas dire qu'on peut les utiliser à loisir  
dans les JTextComponent depuis n'importe quel thread.

Reply

Marsh Posté le 26-01-2005 à 16:07:42    

Ce que je voulais dire c'est que c'est complétement transparent pour le programmeur et dans la majorité des cas, ce n'est pas nécessaire de s'en préoccuper.


---------------
J.C. Farinet
Reply

Marsh Posté le 26-01-2005 à 16:21:40    

[:mlc]

Reply

Marsh Posté le 03-02-2005 à 13:10:26    

Exemple:  
 
en swing :

Code :
  1. public class A extends JFrame {
  2.     JLabel l = new JLabel();
  3.     public A() {
  4.         getContentPane().add(l);
  5.         new Thread(new Timer()).start();
  6.     }
  7.     private class Timer implements Runnable {
  8.         public void run() {
  9.             Date d = new Date();
  10.             while(true) {
  11.                 l.setText(toString(d));
  12.                 Thread.sleep(500);
  13.             }
  14.          }
  15.          public String toString(Date d) {
  16.              // renvoie la date au format lisible
  17.          }
  18.     }
  19. }


 
en SWT :  

Code :
  1. public class A {
  2.     Label l = new Label();
  3.     public A(Shell s) {
  4.         s.add(l);
  5.         new Thread(new Timer()).start();
  6.     }
  7.     private class Timer implements Runnable {
  8.         public void run() {
  9.             Date d = new Date();
  10.             while(true) {
  11.                 Display.getDefault().syncExec(new Runnable() {
  12.                      public void run() {
  13.                           l.setText(toString(d));
  14.                      }
  15.                 });
  16.                 Thread.sleep(500);
  17.             }
  18.          }
  19.          public String toString(Date d) {
  20.              // renvoie la date au format lisible
  21.          }
  22.     }
  23. }


 
En Swing, on n'est pas obligé de faire appel a invokeAndWait() ou invokeLater() pour mettre à jour le champ du label, alors que l'on est obligé de le faire pour SWT.


---------------
J.C. Farinet
Reply

Marsh Posté le 03-02-2005 à 14:01:19    

yo c spi a écrit :

Exemple:  
 
en swing :

Code :
  1. private class Timer implements Runnable {
  2.         public void run() {
  3.             Date d = new Date();
  4.             while(true) {
  5.                 l.setText(toString(d));
  6.                 Thread.sleep(500);
  7.             }
  8.          }
  9.     }




c'est complètement interdit ! c'est marqué dans le lien au-dessus !


Message édité par nraynaud le 03-02-2005 à 14:01:34
Reply

Marsh Posté le 03-02-2005 à 14:16:41    

Le truc vicieux avec ce genre de choses c'est que ça a de bonnes chances de marcher dans la plupart des cas... jusqu'au jour où ça va crasher lamentablement.
D'une manière générale, c'est pareil pour swing et SWt : seul le thread de repartition des evenements doit modifier la gui.
Pour SWT, si tu veux t'affranchir de ce genre de considérations, il y a JFace.


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

Marsh Posté le 03-02-2005 à 15:11:29    

En gros, on devrait toujours utiliser invokeAndWait et invokeLater a chaque appel d'un composant swing si on veut avoir un code copmplétement stable?


---------------
J.C. Farinet
Reply

Marsh Posté le 03-02-2005 à 15:11:29   

Reply

Marsh Posté le 03-02-2005 à 15:13:09    

oui, ou être dans un handler d'évènement (en gros).

Reply

Marsh Posté le 03-02-2005 à 15:13:23    

exactement, mais uniquement quand tu veux agir sur la gui "de l'exterieur" : les callbacks appelés en réponse à des évenements dus à l'utilisateur s'executent dans le thread de repartition des evenements, donc il n'y a pas de problème.
 
[:benou_grilled]


Message édité par R3g le 03-02-2005 à 15:13:40

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

Marsh Posté le 04-02-2005 à 16:02:37    

Ok d'ac, je viens d'apprendre un truc, merci.
 
 
Mais revenons en à ma question de départ :  

yo c spi a écrit :

Je programme les appels aux méthodes comme ceci et je voulais savoir si c'était assez "propre" (ca ne me le semble pas) ou s'il y a une autre méthode de conception plus logique.



---------------
J.C. Farinet
Reply

Marsh Posté le 04-02-2005 à 16:08:51    

à part utiliser .equals() au lieu de ==, c'est ce que je fais perso.

Reply

Marsh Posté le 04-02-2005 à 21:20:13    

nraynaud a écrit :

à part utiliser .equals() au lieu de ==, c'est ce que je fais perso.


Ca n'a pas d'importance ici, si 2 Threads sont "equals", c'est que ce sont les memes, donc meme adresse mémoire.
De plus, la méthode equals sur un Thread est celle de la classe Object qui est (il me semble) :  

Code :
  1. public boolean equals(Object o) {
  2.     return this == o;
  3. }


 
 
Pour en revenir au sujet, moi je ne trouve pas ca très propre la méthode publique appelant la méthode privée "real...".
 
edit :  

Vu dans API Java a écrit :

 The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference values x and y, this method returns true if and only if x and y refer to the same object (x == y has the value true).



Message édité par yo c spi le 04-02-2005 à 21:22:18

---------------
J.C. Farinet
Reply

Marsh Posté le 04-02-2005 à 21:36:59    

[:mlc]
 
vla le couplage et la stabilité.


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

Sujets relatifs:

Leave a Replay

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