2011-05-24 111 views
3

我正在尋找一個簡單的對象,它將保存我的工作線程,我需要它不會限制線程的數量,並且不會使它們的活動時間超過所需的時間。 但我需要它有類似於ExecutorService.shutdown(); 的方法(等待所有的活動線程來完成,但不接受任何新的)在java中的「簡單」線程池

所以也許一個線程池是不是我所需要的,所以我會愛向正確的方向推進。 (因爲他們是爲了保持線程活着)

進一步澄清意圖:

每個線程是一個文件的上傳,而我還有一個過程,修改文件,但它等待文件沒有任何上傳。通過加入每個線程。所以當它們保持活動時,它會鎖定這個過程。 (每個線程都將自己添加到創建時的特定文件的列表中,所以我只加入()線程以上載特定文件)

回答

0

是否有您不想重用線程的原因?在我看來,最簡單的事情就是使用ExecutorService,並讓它重用線程。

+0

每個線程都是一個文件的上傳,而我有另一個修改文件的進程,但它等待文件沒有任何上傳。通過加入每個線程。所以當他們保持活着時,它會鎖定這個過程。 (每個線程都將自己添加到創建時的特定文件的列表中,所以我只加入()線程來上傳特定文件) – Bg1987 2011-05-24 17:01:42

+2

您正在合併兩個概念:線程和任務。任務是「上傳這個文件」,線程是完成任務的可重用資源。任務(可上傳的Runnable)可以在沒有在線程上調用join()的情況下發出「其他進程」的信號。 「其他流程」究竟如何接收這些信號? – 2011-05-24 17:38:08

6

一種方法可以使用CallableFuture,該方法返回已完成上載的File對象。然後將Future傳遞到另一個Callable,該Callable檢查Future.isDone()並旋轉,直到它返回true,然後對文件執行任何您需要的操作。您的使用案例不是唯一的,並且非常適合java.util.concurrentpackage capabilities

一個有趣的類是ExecutorCompletionServiceclass它完全按照你想要的等待結果然後進行額外的計算。

CompletionService使用 提供的Executor執行任務。 本課安排提交的 任務完成後,放在 的隊列中,可以使用take。 類的重量足夠輕以便當 處理任務組時,適合於暫時使用 。

應用實例:假設你有一組求解的一定問題, 每區選出某種類型 結果的價值,並想運行它們 同時,處理結果他們每個人說的 返回非空值 ,在某些方法中使用(Result r)。 你可以這樣寫:

void solve(Executor e, Collection<Callable<Result>> solvers) 
       throws InterruptedException, ExecutionException 
    { 
     CompletionService<Result> ecs = new ExecutorCompletionService<Result>(e); 
     for (Callable<Result> s : solvers) { ecs.submit(s); } 
     int n = solvers.size(); 
     for (int i = 0; i < n; ++i) 
     { 
      Result r = ecs.take().get(); 
      if (r != null) { use(r); } 
     } 
    } 

你不想無限制的ExecutorService的

你幾乎要允許無界線程池,因爲他們實際上可能會限制你的應用程序的性能如果線程數量失控。

您的域受到磁盤或網絡I/O或兩者的限制,因此一個小線程池就足夠了。您不想嘗試從每個連接的線程讀取數百或數千個傳入連接。

您的解決方案的一部分(如果您收到的併發上傳數量較少)是調查java.niopackage並閱讀有關非阻塞I/O。