2008-12-06 95 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