2010-06-10 28 views
3

在這個例子中,我提交了幾個文件到我的比較對象。它一切正常,但我注意到提交文件的順序並不總是與它們返回的順序相同。有關如何更好地控制此問題的任何建議?如何控制Java期貨被「提交」的訂單?

ExecutorService pool = Executors.newFixedThreadPool(5); 
    CompletionService<Properties> completion = new ExecutorCompletionService<Properties>(pool); 

    for (String target : p.getTargetFiles()) { 
    completion.submit(new PropertiesLoader(target, p)); 
    } 

    for (@SuppressWarnings("unused") 
    String target : p.getTargetFiles()) { 
    Properties r = null; 
    try { 
    r = completion.take().get(); 
    } catch (InterruptedException e) { 
    e.printStackTrace(); 
    } catch (ExecutionException e) { 
    e.printStackTrace(); 
    } 

    p.addTargetFilesProperties(r); 
    } 

    pool.shutdown(); 

回答

3

使用CompletionService.take的要點是使其返回取Future已經完成,無論他們提出什麼樣的順序。如果你想返回它們,那麼你可能不會使用它們(你甚至可能根本不想使用CompletionService,但你可以)。請保留從submit()返回的Future對象列表,並在每一個對象上調用.get();它會阻塞,直到結果可用。

0

當一次向ThreadPoolExecutor提交多個任務時,由於它們由多個線程同時執行,因此您無法真正控制終止時間。 完成服務按照它們完成的順序返回它們,這可能因執行而異。如果您決定連續執行任務,則完成順序與激活順序相同。

- 編輯 -

如果你仍然想併發性,但希望等待特定順序的任務,不使用完成的服務。簡單地按要求的順序循環使用期貨,並調用他們的get()方法,如果需要的話可以阻止它。