2014-01-09 55 views
1

我正在創建一個程序,它從用戶接收參數,執行一些複雜的計算,並將值返回給用戶。由於這些計算通常需要一些時間,我希望用戶能夠隨時暫停/恢復或停止計算。我使用多線程來運行計算,但由於我正在使用future.get()來檢索解決方案,因此在計算完成時GUI不響應。這裏是我的代碼:防止future.get()使GUI無法響應以實現暫停按鈕

System.out.println("Starting all threads..."); 
    ExecutorService exec = Executors.newCachedThreadPool(); 
    int threadCount = 4; 
    int amount = 10000000; 
    StringBuilder s = new StringBuilder(); 
    for(int i = 0; i < threadCount; i++) { 
     Future<String> future = exec.submit(new Simulator(inputVariable1,inputVariable2, 
     inputVariable3, inputVariable4, inputVariable5, inputVariable6, amount/threadCount)); 
    //No these are not the real variable names 
     try { 
      s.append(future.get()).append("\n"); 
     } catch (InterruptedException | ExecutionException ex) { 
      Logger.getLogger(StartGUI.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 
    int length = (int)(Math.log10(amount)+1); 
    int start = 0; 
    int totalWins = 0; 
    int totalLosses = 0; 
    for(int i = 0; i < threadCount; i++) { 
     int pos = s.indexOf("Wins: ",start); 
     int end = s.indexOf("Losses: ",start); 
     totalWins += Integer.parseInt(s.substring(pos+6,end-1)); 
     totalLosses += Integer.parseInt(s.substring(end+8,end+7+length)); 
    } 
    println("Total wins: " + totalWins + "\n" + "Total losses: " + totalLosses); 

正如你所看到的,我創建了4個線程,每個線程運行的計算,然後收集來自各個使用的Future.get()的結果。我遇到的問題是我無法在GUI中實現暫停/恢復/停止按鈕,因爲future.get()方法會使GUI無法響應,直到它檢索到數據。關於我能做些什麼來解決這個問題的任何想法?

+0

只是爲了記錄在案,可以測試'Future',看它是否與'做的Future.isDone()'。 – Gray

回答

4

Future#get塊,直到Callable完成,這意味着,您是阻塞事件調度線程,直到Callable完成,這意味着UI可以不再被生成的事件......

一個更好的解決辦法是將使用SwingWorker,這在概念上是相同的,只是它具有向EDT提供反饋的功能,具體而言,在這種情況下,該方法是done。在工作人員完成時調用該工具,但是在EDT的上下文中調用該工具,以便保存以更新UI。

看看Concurrency in Swing,特別Worker Threads and SwingWorker ...

+0

由於某些原因,SwingWorker仍使GUI無響應。 –

+0

你打電話來自美國東部時間?不調用execute和doInBackground來代替?你想讓我繼續猜測還是能夠更新你的問題? – MadProgrammer