2015-09-29 53 views
2

我正在實現Future<Collection<Integer>>接口,以便在應用程序中的所有線程之間共享某些批量計算的結果。實現共享計算的未來接口

其實,我本打算只是把一類implemetnting Future<Collection<Integer>>的實例爲ApplicationScope對象,以便任何其他線程其需要的結果只是從object索要Future並調用該方法get()就可以了,所以用由另一個線程執行的計算。

我的問題是關於實施cancel方法。現在,我會寫這樣的事情:

public class CustomerFutureImpl implements Future<Collection<Integer>>{ 

    private Thread computationThread; 
    private boolean started; 
    private boolean cancelled; 
    private Collection<Integer> computationResult; 

    private boolean cancel(boolean mayInterruptIfRunning){ 
     if(computationResult != null) 
      return false; 
     if(!started){ 
      cancelled = true; 
      return true; 
     } else { 
      if(mayInterruptIfRunning) 
       computationThread.interrupt(); 
     } 
    } 

    //The rest of the methods 
} 

但這種方法實現不滿足Future的文件,因爲我們需要在任何線程等待的結果扔CancellationException(也稱爲get()法) 。

我應該添加另一個字段,如private Collection<Thread> waitingForTheResultThreads;,然後從Collection中斷每個線程,捕獲中斷的異常,然後throw new CancellationException()

事情是,這樣的解決方案似乎對我來說有點奇怪......不知道這一點。

回答

2

通常應該避免直接執行Future。併發代碼爲非常難以獲得,分佈式執行框架 - 特別是ExecutorService - 將提供Future引用您關心的工作單元的實例。

你可能已經知道了,並有意創建一個新的類似的服務,但我覺得它調出,對於廣大大多數使用的情況下,你不應該需要定義自己的Future實現是非常重要的。

您可能想看看Guava提供的併發工具,特別是ListenableFuture,它是Future的子接口,它提供了附加功能。


假設你真的要定義一個定製Future型,利用番石榴的AbstractFuture實施爲出發點,讓你不必重新發明你正在運行到複雜的細節。

爲了您的具體問題,如果你看一下implementation of AbstractFuture.get(),你會看到它有一個while循環,尋找value成爲非空,此時它調用getDoneValue()它要麼返回值或加薪實施一個CancellationException。因此,基本上,在撥打Future.get()時阻止的每個線程每隔一段時間輪詢Future.value字段,如果檢測到Future已被取消,則提高CancellationException。沒有必要跟蹤Collection<Thread>或其他類似的東西,因爲每個線程都可以獨立檢查Future的狀態,並根據需要返回或拋出。

+0

順便說一句,我沒有實際執行它。我只創建了少量冗長的接口,只有三個方法:'public T ensureResult();'如果它還沒有開始計算,並等待它完成,如果某個線程啓動它。方法'isStarted'和'done()'返回計算的狀態。 –

+0

關於這樣的解決方案你會怎麼說? –

+0

聽起來像一個更弱的'未來'。如果沒有更充分的理解你的目標,我不能說這是一個好的解決方案,但總的來說,我鼓勵重用而不是重新創建。 ['供應商'](http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Supplier.html),'ListenableFuture',偶爾還有'AbstractFuture'(以及他們相關的工具類)應該做你需要的大部分事情。 – dimo414