IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

AWT/Swing Java Discussion :

thread java et échange MPI avec un programme C


Sujet :

AWT/Swing Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    57
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Avril 2008
    Messages : 57
    Par défaut thread java et échange MPI avec un programme C
    Bonjour,

    Je dispose d'une classe Java (développée avec JNI) qui me permet d'utiliser depuis un programme Java, les fonctions C de MPI (un 'wrapper' en quelque sorte).

    Ca fonctionne et j'ai pu vérifier que je pouvais faire des SEND depuis un programme java, en correspondance avec des RECEIVE dans un programme C.

    Maintenant, je cherche à introduire ce mécanisme dans une petite appli java constituée d'un Slider et d'un listener sur le changement de valeur du Slider.

    Le programme C consiste simplement en une boucle avec un seul RECEIVE placé au début de cette boucle.

    L'appli Java doit donc faire le SEND vers le programme C depuis une boucle aussi car le SEND et le RECEIVE sont synchrones.

    J'ai placé la boucle qui doit faire le SEND de la valeur du Slider dans un Thread Java.

    Mon problème est le suivant : le thread java envoie la valeur initiale du slider mais il ignore les changements de valeur par déplacement du Slider.

    En revanche, si j'ajoute un délai dans boucle (avec un TimeUnit.SECONDS.sleep(2); ) ça fonctionne et la valeur envoyée est actualisée !

    Sauriez-vous m'éclairer sur ce qui se passe, car ce "remède" n'est pas très satisfaisant, et le résultat n'est pas robuste du tout...

    Ci dessous le code de l'appli du Slider (vous verrez que le main() ne fait que créer un nouveau thread pour exécuter la fameuse boucle).
    Et juste après, le code du Thread qui exécute la boucle avec le SEND

    Merci d'avance pour votre aide...


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
     
    package power;
     
    import java.awt.GridLayout;
    import java.util.Hashtable;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JSlider;
    import javax.swing.event.ChangeEvent;
    import javax.swing.event.ChangeListener;
     
    public class Widget  extends JPanel {
     
        static public double value;
     
    	public static void main(String[] args) throws InterruptedException {
     
    		// Create and set up a frame window
    		JFrame.setDefaultLookAndFeelDecorated(true);
    		JFrame frame = new JFrame("Slider with change listener");
    		frame.setSize(500, 500);
    		frame.setLayout(new GridLayout(3, 1));
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		JPanel panel1 = new JPanel();
    		JPanel panel2 = new JPanel();
     
    		final JLabel status = new JLabel("Slide the slider and you can get its value", JLabel.CENTER);
     
                    // Set the slider
    		JSlider slider = new JSlider();	
    		slider.setMinorTickSpacing(10);
    		slider.setPaintTicks(true);
     
    		// Set the labels to be painted on the slider
    		slider.setPaintLabels(true);
     
    		// Add positions label in the slider
    		Hashtable<Integer, JLabel> position = new Hashtable<>();
    		position.put(0, new JLabel("0"));
    		position.put(50, new JLabel("50"));
    		position.put(100, new JLabel("100"));
     
    		// Set the label to be drawn
    		slider.setLabelTable(position);
     
    		// Add change listener to the slider
    		slider.addChangeListener(new ChangeListener() {
    			public void stateChanged(ChangeEvent e) {
    				status.setText("Value of the slider is: " + ((JSlider)e.getSource()).getValue());
                                    Widget.value=1.0*((JSlider)e.getSource()).getValue();
    			}
    		});
     
    		// Add the slider to the panel
    		panel1.add(slider);
     
    		// Set the window to be visible as the default to be false
    		frame.add(panel1);
    		frame.add(status);
    		frame.add(panel2);
    		frame.pack();
    		frame.setVisible(true);
     
                    // Boucle pour les envois MPI 
                    loop l = new loop(); 
                    l.start();
     
    	}
    }
    Ci-dessous le thread qui exécute la boucle pour faire le SEND :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
     
    import fr.moi.jnimpi.MPIInterface;
    import java.util.concurrent.TimeUnit;
    import java.util.logging.Level;
    import java.util.logging.Logger;
     
    /**
     *
     * @author pierre
     */
    public class loop extends Thread{
     
        @Override
        public void run() {
     
                    MPIInterface.begin();
     
                    int size = MPIInterface.size();
                    int rank = MPIInterface.rank();
                    String name = MPIInterface.processorName();
                    System.out.printf("Java Process %d on %s out of %d \n", rank, name, size);
                    int time=0;
                    double[] sentData = {Widget.value};
     
                   while(time<100)
                    {
                        time +=1;
                        sentData[0]=Widget.value;
                        MPIInterface.send(1, sentData);
     
    //                    try {
    //                        TimeUnit.SECONDS.sleep(2);
    //                    } catch (InterruptedException ex) {
    //                        Logger.getLogger(loop.class.getName()).log(Level.SEVERE, null, ex);
    //                    }
     
                    }  
                    MPIInterface.end();       
        }  
    }

  2. #2
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Alors pourquoi ça ne change pas?

    Parce que la variable à laquelle tu accède n'a pas été indiquée comme pouvant être modifiée par un autre Thread et donc le JVM fait des optimisation qui empêchent de voir les modifs faites par le widget.

    Pour résoudre, il y a la méthode dégeulasse: marque le champ comme volatile.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    static volatile public double value;
    Par contre, il y a la méthode propre en java.

    D'abord, tout ce qui concerne la lecture de valeur d'un composant, ca doit être fait dans le thread swing. On ne peut lire / modifier la valeur d'un composant swing que dans celui-ci. Sous peine de bizarreries comportementales.
    Ensuite, tu ne peux pas faire des choses bloquantes (genre envoyer vers ton serveur) depuis le thread Swing.

    Pour résoudre ça, il y a le swingWorker, équipé d'une partie lisant les composants et une partie faisant le travail dans un Thread à part.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class SendTask extends
             SwingWorker<Void, Void> {
         double[] toSend;
         PrimeNumbersTask(Widget widget) {
             toSend={Widget.value};
         }
     
         @Override
         public Void doInBackground() {
             MPIInterface.send(1, sentData);
             return null;
         }
     }
    et dans ton listener du slider:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    new SendTask(widget).execute();
    Autre option en supposant que ton problème principal c'est que tu ne peux faire qu'un seul envoi à la fois, j'utiliserais un ExecutorService avec un seul Thread pour faire le travail, et dans le listener du slider j'aurais



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    executorService = Executor.newSingleThreadExecutor();
    .....
     
    double[] sentData = {widget.value}
    executorService .submit({}->MPIInterface.send(1, sentData));

    après on peu rendre ça tout propre en mettant le tout dans une classe dont le boulot c'est d'avoir des méthode qui submittent dans le services les différentes demandes.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    57
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Avril 2008
    Messages : 57
    Par défaut Merci
    @Tchize : Un grand merci pour ces conseils, je vais les tester ce soir et je viendrai mettre le résultat dans le forum...

Discussions similaires

  1. Souci JDBC avec Mysql, programmation JAVA
    Par Danzel dans le forum Windows
    Réponses: 8
    Dernier message: 29/12/2006, 21h46
  2. JSmooth avec des programmes Java conséquents...
    Par phyll dans le forum API standards et tierces
    Réponses: 7
    Dernier message: 28/04/2006, 10h25
  3. Réponses: 11
    Dernier message: 14/02/2006, 00h26
  4. Debutant en JAVA, problème avec 1er programme
    Par Gymerus dans le forum Entrée/Sortie
    Réponses: 13
    Dernier message: 07/09/2005, 12h10
  5. [votre avis m'interesse] Interface avec un programme Java
    Par LineLe dans le forum Interfaces Graphiques en Java
    Réponses: 29
    Dernier message: 11/12/2004, 11h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo