我的问题涉及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()
事件。
是
答案 0 :(得分:1)
又是什么主线?
让我看看我是否做对了。
后台线程触发GUI可以拦截的事件,以便知道数据已准备就绪。
这是对的吗?
您可以使用SwingUtilities.invokeLater(Runnable r);
在处理该线程中当前所有事件之后,它在AWT事件调度线程中插入该runnable实例(我猜这与主线相同)。
通过这种方式,您可以触发“actionPerformed”事件,并且已注册的侦听器将正确处理。
让我快速编写代码,然后告诉我这是否是你想要的。
答案 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