Запуск основного события из фонового потока в Java - PullRequest
1 голос
/ 06 декабря 2008

Мой вопрос касается многопоточности в Java. Я перевожу приложение, написанное в Visual Basic 2008, на Java. В VB есть класс BackgroundWorker , который позволяет кодировщику выполнять задачу в другом потоке, во многом как SwingWorker в Java. Единственное отличие состоит в том, что поток BackgroundWorker равен run() и запускает событие с именем DoWork() на главной линии, которое содержит код для выполнения в фоновом режиме. Кроме того, после выполнения кода событие RunWorkerCompleted() отправляется обратно в поток переднего плана для интерпретации результатов.

Мне показалось, что установка BackgroundWorker весьма полезна, и она кажется немного более гибкой, чем SwingWorker, и мне просто было интересно, можно ли (и приемлемо) запускать события таким же образом в Java? И если так, как бы я поступил об этом? Поскольку я только сделал быстрое сканирование на SwingWorker, вполне возможно, что он имеет аналогичную функциональность, которая будет работать так же хорошо, и в этом случае я был бы рад узнать об этом вместо этого.

Приветствия

шумиха

EDIT:

Kewl. Приветствия, ребята, спасибо за быстрые ответы и извинения за мой довольно медленный ответ. Я поделюсь с вами вашей идеей, Оскар, извините, коберд, я не совсем поняла - приветствуются любые дальнейшие объяснения (возможно, пример).

Напомню: я хочу иметь исполняемый класс, экземпляр которого создаю в своем коде. У класса runnable есть два события, одно из которых запускается из фонового потока и содержит код для запуска в фоновом режиме (DoWork()), а другое событие вызывается в потоке переднего плана после того, как фоновый поток завершил свою задачу ( RunWorkerCompleted()).

И если я правильно понимаю ваш совет, я могу запустить событие DoWork() из метода runnable class 'run(), чтобы оно выполнялось в фоновом потоке, а затем я могу использовать метод SwingUtilities.invokeLater() для инициировать событие RunWorkerCompleted() в потоке переднего плана, как только фоновый поток завершит выполнение.

Да

Ответы [ 3 ]

1 голос
/ 06 декабря 2008

Что снова стало магистралью?

Дай мне посмотреть, правильно ли я понял.

Фоновый поток запускает событие, которое GUI может перехватить, чтобы узнать, что данные готовы.

Это правильно?

Вы можете использовать SwingUtilities.invokeLater (Runnable r);

Он вставляет этот запускаемый экземпляр в поток диспетчеризации событий AWT (который, я думаю, совпадает с основной линией) после обработки всех событий, которые в данный момент находятся в этом потоке.

Таким образом, вы можете запустить событие «actionPerformed», и зарегистрированный слушатель будет обрабатывать правильно.

Позвольте мне действительно быстро что-нибудь кодировать, и вы скажете, было ли это то, что вы хотели.

А пока посмотрите сюда

0 голосов
/ 06 декабря 2008

Единственное намерение следующего кода - показать, как он выглядит при использовании метода SwingUtilities.invokeLater.

В результате задача выполняется в потоке AWT-Event (отвечающем за рисование компонента).

Остальное (создание нового потока, создание графического интерфейса и т. Д.) - это просто код скаффолда.

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 ");
        }
    };


}

Вывод похож на:

Thread-2 Started background task
Thread-2 Finished background task
AWT-EventQueue-0 start setting text
AWT-EventQueue-0 finish setting text
0 голосов
/ 06 декабря 2008

Не совсем уверен, поможет ли это, но, глядя на SwingWorker из Java 6 (который является новым и отличается от предыдущих выпусков), и на Java Tutorials по этому вопросу, он может предложить нечто подобное к тому, что вы можете быть после.

Взглянув на раздел Параллельность в Swing Учебников Java, в нем есть раздел Связанные свойства и методы состояния , в котором упоминается способ регистрации PropertyChangeListener в SwingWorker. Таким образом, любые события, для которых вы хотите уведомить другой поток, могут быть выполнены путем создания PropertyChangeEvent s с помощью методов firePropertyChange.

Кроме того, см. Раздел о SwingWorker теперь включен в раздел Дополнительные улучшения в Java SE 6 , где приведено краткое описание выше.

Итак, если я правильно понимаю, что статьи, во-первых, реализуем PropertyListener в потоке, куда следует отправлять сообщения из потока SwingWorker. Затем, чтобы отправить сообщение обратно в исходную ветку, изменения свойства запуска, запущенные с SwingWorker в его doInBackground() (с использованием метода firePropertyChange), могут использоваться в качестве средства отправки сообщений другому.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...