2011-12-14 53 views
2

我有一個相對大量的代碼,沒有考慮到線程。我是Java新手,一般編程,所以我在計算如何運行我在線程中構建的程序時遇到了一些麻煩,而無需返回所有類並將其更改爲具有run()方法。我甚至無法想象,如果我有多個方法可以與其他類分開調用,那麼這是多麼可能。Java:沒有所有具有public void run()的類的線程工作?

我似乎無法找到一種方法來創建一個線程(每/一個)新的來自GUI的代碼調用。假設我有一種將數據插入數據庫的方法。該方法被命名和書寫。我可以把這個類和方法調用到我的main中,但是當我想調用其他方法時呢?至少我有25種以上的方法,而且我看不到我的主要班級被超載25次爲「最佳實踐」。有沒有辦法創建一個線程並給它一個動態處理的對象,這麼說呢?

總之:我想在我的程序中使用線程,而不會重載我的main,我該怎麼做?

+5

如果你的代碼不是專門寫是線程安全的,它不會在多個線程上正常工作。正確的,高性能的多線程開發是_hard_。 – SLaks 2011-12-14 00:51:09

+6

這聽起來像你可能不得不多學習多線程編程。這本書是(在Java中)就這個話題很好的參考:http://jcip.net/ – Bruno 2011-12-14 00:53:34

+0

你爲什麼要在多線程運行呢? – Tom 2011-12-14 00:57:35

回答

1

您不需要每個方法/類在其自己的線程中運行,或者實現run方法。你應該做的是對於用戶可以執行的每個動作,應該有一個相應的類來實現一個動作(或類似的接口)。當用戶在UI上調用動作時,應該將該動作添加到隊列中。

一個單獨的線程池應該從隊列中執行動作並執行它們(通過動作接口公開的方法)。

您需要確保每個操作都是線程安全的並且能夠與其他操作同時運行。這不是一個簡單的任務,並且通常不是初學者能夠做的事情。

僅僅將渲染代碼與處理代碼分開(因此只有2個線程,用戶一次只能運行一個動作),這可能就足夠了。

1

沒有必要讓所有的類都具有run方法或實現Runnable通常在單獨的線程中有特定的事情要做,所以當你執行一個潛在的緩慢操作時你經常會鎖定UI就像談論數據庫,文件系統或網絡一樣。

最簡單的方法是隻創建一個新的線程,當你需要這樣做:

Thread t = new Thread() { 
    public void run() { 
     // do whatever work you want... 
    } 
}; 

t.start(); 
0

您可以創建一個匿名內部類,做任何你需要的。考慮下面的內容。創建一個Runnable的新(未命名)子類,它執行所需的實際步驟。

public class GuiCommandDelegator { 

    void performBackgroundSave(final Document document, final String filename) { 
     Runnable runnable = new Runnable() { 
      @Override void run() { 
       document.save (filename); 
      } 
     }; 

     Thread thread = new Thread(runnable); 
     thread.run(); 
    } 

} 

當然也有缺點,但它會更糟全部通過那些已經專門用於特定用途類灑線程管理代碼。

3

老實說,沒有通用的方式將單線程應用程序轉換爲多線程,因爲它根據您的目標需要不同的設計。而「多線程應用程序」並不是一個真正的目標:)

您沒有指定如何構建您的用戶界面。但是,如果您使用Swing並想在不凍結用戶界面的情況下執行一些冗長的任務,請使用SwingWorker

關於一般說明,我建議您閱讀本書「Java Concurrency in Practice」。這個很不錯。

0

因爲你沒有在你的應用程序線程目前,我建議你考慮使用執行人框架並行應用程序。在這兩種情況下,您都必須創建Runnable實例。 JCIP書提供了一個示例章節,它可以幫助你解決這個問題。如果你不想最終創造25+ Runnable的內部類,你可以創建一個單獨的定製Runnable接口的類,uses reflection to invoke those methods for you

public ReflectiveRunnable { 

    private final Object target; // needs to be non-null 
    private final String methodName; 
    private final Object[] argValues; 
    private final Class[] argClasses; 

    public ReflectiveRunnable(Object target, String methodName, Object[] args) { 
    this.target = target; 
    this.methodName = methodName; 
    this.argValues = args; 
    this.argClasses = new Class[args.length]; 
    for (int i = 0; i < args.length; i++) { 
     argClasses[i] = args[i].getClass(); 
    } 
    } 


    public void run() { 
    try { 
     final Class cl = target.getClass(); 
     final Method mthd=cl.getMethod(methodName, argClasses); 
     mthd.invoke(target, argValues); 
    } catch (final Exception e) { 
     // handle exception 
     e.printStackTrace(); 
    } 
    } 
} 
相關問題