2014-10-18 110 views
0

今天我發現了java中的線程。現在我正處於想讓線程對我的GUI進行更改的地步。我有這兩個實現。我不知道他們之間是否有很大差異。 但是沒有期貨的第一個'掛'了我的程序。我的gui變得反應遲鈍等等。第二個似乎更好。任何人都可以解釋我哪一個最好,爲什麼?期貨和設置內線程之間的區別

Runnable hasherRunnable = new Runnable() { 
     public void run() { 

      notifyObservers(getHasher().hash(input)); 

     }}; 

     this.getPool().submit(hasherRunnable,"hasherThread"); 
    Callable<String> callableHasher=new Callable<String>(){ 
     public String call(){ 
      return getHasher().hash(input); 
     } 
    }; 
    ============================================================ 
    Future<String> future = this.getPool().submit(callableHasher); 
    try { 
     notifyObservers(future.get()); 
    } catch (InterruptedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (ExecutionException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
+2

_I想要線程改變我的gui_這是不允許的。只有一個線程可以更新UI,這就是Event Dispatch Thread。請參見[併發中的擺動](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/)教程 – Robin 2014-10-18 16:08:38

+0

我的gui是'觀察'一個類,它啓動一個新的線程。該新線程使用字符串運行notifyObserver。那個字符串然後顯示在gui上。有用。爲什麼不允許?我該如何解決這個問題? – Bosiwow 2014-10-18 16:10:34

+1

你不能*修復這個*,這是Swing的工作原理。 – m0skit0 2014-10-18 16:12:45

回答

3

您不應該從除事件調度線程(EDT)以外的任何線程更新GUI。要在EDT,使用運行可運行:

EventQueue.invokeLater(new Runnable(){ 
      @Override 
      public void run() { 

      } 
     }); 

搖擺也有SwingWorkers這是工作線程,你可以用做掉EDT費時的操作並獲取即時更新回到GUI。您可以使用它們像這樣:

new SwingWorker<T,T>(){ 
     @Override 
     public Void doInBackground(){ 
      return t; //Object of some type T 
     } 

     @Override 
     public void done() { 
      try { 
       T somVariable = get(); 
       // Use someVariable to update the GUI 
      } 
      catch (InterruptedException ignore) { 
      // handle exception 
      } 
      catch (java.util.concurrent.ExecutionException e) { 
      // handle exception 
      } 
     }.execute(); 

SwingWorkers使它很多更加容易對付期貨。有關這些的更多信息,請閱讀工作線程上的Java tutorials