从Java中的后台线程触发主线事件

时间:2008-12-06 03:05:35

标签: java multithreading events

我的问题涉及Java中的多线程。我正在将我在Visual Basic 2008中编写的应用程序翻译成Java。 VB中有一个名为BackgroundWorker的类,它允许编码器在另一个线程上执行任务,就像Java中的SwingWorker一样。唯一明显的区别是,BackgroundWorker线程为run(),它会在主线上触发一个名为DoWork()的事件,其中包含要在后台执行的代码。此外,代码执行后,会在前台线程上触发RunWorkerCompleted()事件来解释结果。

我发现BackgroundWorker设置非常有用,它似乎比SwingWorker更灵活一点,我只是想知道在Java中以同样的方式触发事件是否可能(并且可以接受) ?如果是这样,我该怎么做呢?由于我只对SwingWorker进行了快速扫描,因此它可能具有类似的功能,也可以使用,在这种情况下,我很乐意知道这一点。

干杯,

喧闹

编辑:

KEWL。干杯们,谢谢你的回复,并为我相当时间的回复道歉。我会给你的想法一个去奥斯卡,抱歉coobird,我没有完全遵循 - 任何进一步的解释将是受欢迎的(也许是一个例子)。

回顾一下:我希望有一个可运行的类,我在我的代码中实例化一个实例。 runnable类有两个事件,其中一个从后台线程触发并包含在后台运行的代码(DoWork()),另一个事件在后台线程完成后触发前台线程任务(RunWorkerCompleted())。

如果我理解你的建议,我可以从runnable类'DoWork()方法中激活run()事件,以便它在后台线程上执行,然后我可以使用{ {1}}方法在后台线程完成执行后触发前台线程上的SwingUtilities.invokeLater()事件。

3 个答案:

答案 0 :(得分:1)

又是什么主线?

让我看看我是否做对了。

后台线程触发GUI可以拦截的事件,以便知道数据已准备就绪。

这是对的吗?

您可以使用SwingUtilities.invokeLater(Runnable r);

在处理该线程中当前所有事件之后,它在AWT事件调度线程中插入该runnable实例(我猜这与主线相同)。

通过这种方式,您可以触发“actionPerformed”事件,并且已注册的侦听器将正确处理。

让我快速编写代码,然后告诉我这是否是你想要的。

平均时间take a look at here

答案 1 :(得分:0)

不确定这是否会有所帮助,但是看看Java 6中的SwingWorker(这是新的,与以前的版本不同),以及关于此事的Java教程,它可能提供类似于什么的东西你可能会追求。

看一看The Java Tutorials的Concurrency in Swing部分,它有一个关于Bound Properties and Status Methods的部分,其中提到了一种向PropertyChangeListener注册SwingWorker的方法。这样,您可以通过PropertyChangeEvent方法创建firePropertyChange来执行要通知其他线程的任何事件。

另请参阅More Enhancements in Java SE 6文章中有关SwingWorker现在包含的部分,以获取上述内容的快速说明。

因此,如果我理解文章的正确性,首先,在应该发送PropertyListener线程的消息的线程上实现SwingWorker。然后,要发送消息以回到原始线程,可以使用SwingWorker doInBackground()firePropertyChange触发的触发属性更改(使用{{1}}方法)作为发送消息的方法另一个。

答案 2 :(得分:0)

以下代码的唯一目的是展示使用SwingUtilities.invokeLater方法时的样子。

效果是任务在AWT-Event线程(负责组件绘制的线程)中执行。

其余的(创建新线程,创建gui等)只是脚手架代码。

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