2012-03-20 184 views
6

我有一個多線程的實現,我創建一個ExecutorService並提交要執行的任務,我想知道什麼時候所有線程都已完成而沒有阻塞主線程和UI。我試過ExecutorService.awaitTermination(),但它阻止了主線程和用戶界面。我搜索了很多,但我似乎無法找到一個這樣做的優雅方式。我目前正在考慮創建另一個線程來計算完成的線程數量,並在完成時啓動一個事件,但這不是一個好方法,而且我想要一個更好的解決方案!ExecutorService,如何知道所有線程何時完成而不阻塞主線程?

+0

你的主線程做的,它不能被阻止什麼? – EJP 2012-03-20 00:42:58

+0

你使用什麼UI工具包? – Dev 2012-03-20 00:44:12

回答

2

isTerminated()會做

不過請注意,這兩個awaitTerminationisTerminated只會給你一個有意義的結果,你都呼籲shutdown

+0

我發現了一些關於isTerminated()的內容,但仍然認爲我需要在「side thread」上運行它來經常檢查它是否返回true,從而將我帶入我的初始解決方案! – Trota 2012-03-20 00:15:11

7

使用SwingWorker來關閉線程池,並調用awaitTermination()後。這將防止UI阻塞,並從SwingWorker實現上的Event Dispatch Thread中調用done(),您可以使用它來觸發您所需的任何UI更改。

如果您希望跟蹤通過UI更新運行的線程,則可以使用工作線程在一個循環中監控此線程,並調用publish(),然後將參數傳遞給EDT上的process()實現。

+1

他從來沒有提到這是一個Swing應用程序,如果沒有,那麼SwingWorker將不合適。 – 2012-03-20 00:37:12

+1

我忘了提及它是一個Swing應用程序! – Trota 2012-03-20 00:44:42

+0

閱讀了更多關於SwingWorker後,我意識到這是一個相當簡單的解決方案,我的問題!謝謝Dev! – Trota 2012-03-20 00:50:55

4

爲什麼不使用CountDownLatch,然後在閂鎖完成時通知主線程。

+1

好主意;有一個很好的例子[這裏](http://stackoverflow.com/a/3588523/230513)。 – trashgod 2012-03-20 05:09:53

+1

@trashgod剛剛在你的文章中留言:這個例子在訪問文本組件的EDT時出現了一個小故障 – kleopatra 2012-03-20 11:20:52

2

您可以維護一個單獨的線程在執行服務實例關閉追蹤:

final ExecutorService execSvc = ...; 
    execSvc.submit(task1); 
    ... 
    execSvc.submit(taskN); 
    // important to request the exec service to shut down :) 
    execSvc.shutdown(); 

    new Thread(new Runnable() { 

     public void run() { 
      while (!execSvc.isTerminated()) { 
       try { 
        execSvc.awaitTermination(60, TimeUnit.SECONDS); 
       } catch (InterruptedException e) { 
        // ignore exception 
       } 
      } 
      System.out.println("ExecSvc.run: exec service has terminated!"); 
      // possibly submit a task using SwingUtilities.invokeLater() to update the UI 
     } 

    }).start(); 
2

使用CountDownLatch

 

CountDownLatch latch = new CountDownLatch(totalNumberOfTasks); 
ExecutorService taskExecutor = Executors.newFixedThreadPool(4); 
while(...) { 
    taskExecutor.execute(new MyTask()); 
} 

try { 
    latch.await(); 
} catch (InterruptedException E) { 
    // handle 
} 

,你的任務中

(在嘗試/最後附上)
 latch.countDown(); 

或者在您調用shutdown()的ExecutorService上,然後在awa itTermination()

 
ExecutorService taskExecutor = Executors.newFixedThreadPool(4); 
while(...) { 
    taskExecutor.execute(new MyTask()); 
} 
taskExecutor.shutdown(); 
try { 
    taskExecutor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); 
} catch (InterruptedException e) { 
    ... 
} 

也看看THIS答案

+0

除非我誤解了我的理解,否則這兩種解決方案都不能解決OP的基本問題,即避免主要阻塞線。 – Trevor 2014-06-22 12:41:14

相關問題