2012-01-17 87 views
2

我不知道下面的是一個正確實施實現線程

ExecutorService pool = Executors.newFixedThreadPool(MAX_NSH_THREADS); 
    Set<Future<Void>> futureRequest = new HashSet<Future<Void>>(); 

    for (String host : SomeCollection)) { 
     Callable<Void> callable = new FileExtractor(j); 
     Future<Void> future = pool.submit(callable); 
     futureRequest.add(future); 
    } 

    for (Future<Void> future : futureRequest) { 
     try { 
      future.get(); 
     } catch (Exception e) { 
      logger.error(e); 
     } 
    } 

    pool.shutdown(); 

根據的Javadoc,future.get()等待執行完成的每個線程,(據我所知)意味着對於每個未來,我們將等待分開收到結果。從那裏得到什麼好處呢,還是我做得不對?

+0

你試圖得到什麼好處?這看起來好像會起作用,但是,是的,它只是等待所有的未來完成之後才關閉游泳池...... – elijah 2012-01-17 21:59:34

回答

4

你做得對。

假設SomeCollection包含100個項目,並且FileExtractor需要5秒運行,並且您的ExecutorService線程池包含100個線程。

如果您按照以上實施的方式啓動,預計代碼將運行約5秒鐘,因爲FileExtractor可能會受I/O限制。 (假設最大的CPU效率)。

如果您沒有使用Future's,並且所有內容都是連續運行的,則此代碼將運行約500秒。

的關鍵是,Future#get()等待結果開始由Thread填充提交您CallableExecutorService,而不是在ExecutorService#submit(Callable)方法等。

2

通過致電pool.submit,您將提交每個未來。如果您的主線在此期間還有其他工作要做(在開始期貨和等待它們結束之間),那麼很容易發生這樣的情況,即所有的期貨都是在到達第二個循環時完成的,因此實際上不要阻塞。

如果get方法確實會阻塞主線程,但在等待第一個Future完成時,請注意其他線程仍在並行運行(至少在給定的處理器時間的情況下)。