2008-12-06 8 views
1

Ma question concerne le multi-threading en Java. Je suis en train de traduire une application que j'ai écrite en Visual Basic 2008 en Java. Il existe une classe en VB appelée BackgroundWorker, qui permet au codeur d'effectuer une tâche sur un autre thread, un peu comme en Java. La seule différence distincte est que, avec le thread BackgroundWorker est run(), il déclenche un événement appelé DoWork() sur la ligne principale qui contient le code à exécuter en arrière-plan. En outre, après l'exécution du code, un événement RunWorkerCompleted() est renvoyé sur le thread de premier plan pour interpréter les résultats.Lancement d'un événement mainline à partir d'un thread d'arrière-plan en Java

J'ai trouvé l'installation BackgroundWorker assez utile et il semble un peu plus souple que SwingWorker et je me demandais juste s'il était possible (et acceptable) de déclencher des événements de la même manière en Java? Et si oui, comment pourrais-je y aller? Comme je n'ai effectué qu'un balayage rapide sur SwingWorker, il est possible qu'il ait une fonctionnalité similaire qui fonctionne aussi bien, auquel cas je serais heureux de le savoir à la place.

Cheers,

Hoopla

EDIT:

Kewl. Bravo les gars, merci pour les réponses rapides, et les excuses pour ma réponse plutôt laxiste. Je vais donner votre idée à Oscar, désolé coobird, je n'ai pas tout à fait suivi - toute autre explication serait la bienvenue (peut-être un exemple). Juste pour récapituler: Je veux avoir une classe exécutable, que j'instancie une instance de dans mon code. La classe runnable a deux événements, dont l'un est tiré du thread d'arrière-plan et contient le code à exécuter en arrière-plan (DoWork()), et l'autre événement est déclenché sur le thread de premier plan après que le thread d'arrière-plan a terminé sa tâche (RunWorkerCompleted()) .

Et si je comprends bien vos conseils correctement, je peux tirer l'événement DoWork() de la classe runnable méthode run() de sorte qu'il sera exécuté sur le thread d'arrière-plan, puis je peux utiliser la méthode SwingUtilities.invokeLater() pour déclencher l'événement RunWorkerCompleted() sur le fil de premier plan, une fois le thread d'arrière-plan a terminé l'exécution.

Oui?

Répondre

0

La seule intention du code suivant est de montrer à quoi cela ressemble lorsque la méthode SwingUtilities.invokeLater est utilisée.

L'effet est que la tâche est exécutée dans le thread AWT-Event (celui responsable de la peinture des composants).

Le reste (créer un nouveau fil, créer un gui etc.) est juste du code d'échafaudage.

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 

public class InvokeLaterEffect { 

    static JTextArea text = new JTextArea(); 


    // See the diff by commenting. 
    static void done() { 
     SwingUtilities.invokeLater(doneAction); 
     //doneAction.run(); 
    } 


    public static void main(String [] args) { 
     JFrame frame = new JFrame(); 
     frame.add(text); 
     frame.pack(); 
     frame.setVisible(true); 

     bacgroundTask.start(); 
    } 
    // run a task in the background 
    static Thread bacgroundTask = new Thread(){ 
     public void run(){ 
      try { 
       System.out.println(Thread.currentThread().getName() + " Started background task "); 
       Thread.sleep(5000); 
       System.out.println(Thread.currentThread().getName() + " Finished background task"); 
       done(); 
      } catch (InterruptedException ie){} 
     } 
    }; 

    // called whtn id done 
    static Runnable doneAction = new Runnable(){ 
     public void run(){ 
      System.out.println(Thread.currentThread().getName() + " start setting text "); 
      text.setText("Hello"); 
      System.out.println(Thread.currentThread().getName() + " finish setting text "); 
     } 
    }; 


} 

La sortie est comme:

Thread-2 Started background task 
Thread-2 Finished background task 
AWT-EventQueue-0 start setting text 
AWT-EventQueue-0 finish setting text 
1

Quelle était la ligne principale à nouveau?

Laissez-moi voir si je comprends bien.

Le fil d'arrière-plan déclenche un événement que l'interface graphique peut intercepter pour savoir que les données sont prêtes.

Est-ce correct?

Vous pouvez utiliser SwingUtilities.invokeLater (Runnable r);

Il insère cette instance exécutable dans le thread d'envoi d'événement AWT (que je suppose est identique à la ligne principale) après que tous les événements actuellement dans ce thread sont traités.

De cette façon, vous pouvez déclencher un événement "actionPerformed" et l'écouteur enregistré gérera correctement. Permettez-moi de coder quelque chose très rapidement et vous me direz si c'était ce que vous vouliez.

Dans le même temps take a look at here

0

Pas exactement sûr si cela va aider, mais en regardant le SwingWorker de Java 6 (ce qui est nouveau et différent des versions précédentes), et Java Tutoriels sur la question, il peut offrir quelque chose de similaire à ce que vous pourriez être après.

Jeter un oeil à la section Concurrency in Swing de Java Tutoriels, il a une section sur Bound Properties and Status Methods qui mentionne un moyen d'enregistrement d'un PropertyChangeListener au SwingWorker. De cette façon, tous les événements pour lesquels vous souhaitez notifier un autre thread peuvent être effectués en créant PropertyChangeEvent via les méthodes firePropertyChange.

En outre, consultez la section sur la section SwingWorker est maintenant incluse de l'article More Enhancements in Java SE 6 pour une description rapide de ce qui précède. Donc, si je comprends ce que les articles correctement, d'abord, mettre en œuvre un PropertyListener sur le thread où les messages du fil SwingWorker doivent être envoyés. Ensuite, pour renvoyer un message au thread d'origine, le déclenchement des modifications de propriété provenant du SwingWorker dans son doInBackground() (en utilisant la méthode firePropertyChange) pourrait être utilisé comme moyen d'envoyer des messages à un autre.

+0

Yeap PROMETTEURS – OscarRyz

Questions connexes