2008-12-06 94 views
1

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

我发现BackgroundWorker安装非常有用,它看起来比SwingWorker更灵活,我只是想知道是否可以(并且可以接受)在Java中以相同的方式触发事件?如果是的话,我会怎么做呢?由于我只通过SwingWorker进行了快速扫描,因此它可能具有类似的功能,而且可以正常工作,在这种情况下,我很乐意了解这一点。

干杯,

喧闹

编辑:

KEWL。欢呼家伙,感谢您的及时回复,并对我相当时间不严的回复表示歉意。我会把你的想法放在一个奥斯卡,抱歉coobird,我没有完全遵循 - 任何进一步的解释将受到欢迎(也许是一个例子)。

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

如果我正确地理解你的建议,我可以火从运行的类run()方法DoWork()事件,因此,它会在后台线程来执行,然后我可以使用SwingUtilities.invokeLater()方法火RunWorkerCompleted()事件上前景线程,一旦后台线程完成执行。

是吗?

回答

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 
1

又是什么主线?

让我看看我是否得到这个权利。

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

这是正确的吗?

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

在处理完该线程中当前所有事件后,它将该可运行实例插入到AWT事件分派线程中(我猜与主线相同)。

这样你可以触发一个“actionPerformed”事件,注册的侦听器将正确处理。

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

在平均时间take a look at here

0

不能完全确定这是否会帮助,但看SwingWorker从Java 6(这是新的,从以前的版本不同),并就此事在Java教程,它可能会提供类似于您可能会遇到的事情。

考虑看看Java教程的Concurrency in Swing部分,它具有提到注册PropertyChangeListenerSwingWorker的方式上Bound Properties and Status Methods的部分。这样,任何想要通知另一个线程的事件都可以通过firePropertyChange方法创建PropertyChangeEvent来执行。

此外,请参阅More Enhancements in Java SE 6文章中有关SwingWorker Is Now Included的部分,以便快速了解上述内容。

所以,如果我理解什么文章正确,首先在SwingWorker线程应发送到的线程上实现PropertyListener。然后,要发送消息返回到原始线程,可以使用从SwingWorker在其doInBackground()(使用firePropertyChange方法)中触发的触发属性更改作为向其他消息发送消息的方法。

+0

叶氏是看好 – OscarRyz 2008-12-06 03:44:01