2013-09-24 3 views
5

GuavaのListeningExecutorServiceは既存のExecutorServiceをラップすることによって実装されているため、execute()メソッドをインターセプトすることでタスクを「デコレート」します。つまり、基本のExecutorServiceでカスタムPriorityQueueを使用する場合、コンパレータは装飾されたタスクをオリジナルの代わりにListenableFutureTaskオブジェクトとして "見ます"ことを意味します。ListeningExecutorServiceでPriorityBlockingQueueを使用するにはどうすればよいですか?

ラップするタスクを保持する方法はありますか?そのため、キューのコンパレータはタスクの重みを使って順序を決定できますか?

答えて

4

​​ではなく、submit()とお考えですか? (私の応答の一番下を参照してください)

MoreExecutors.listeningDecorator(参照のラッパーの種類)からListeningExecutorServiceを入力すると、あなたは不運です。 listeningDecoratorは、ほとんどのExecutorServiceの実装と同様に、FutureTaskの中のすべての入力をsubmitにラップします。この問題の通常の解決方法は、AbstractExecutorServiceを実装し、newTaskForをオーバーライドしてカスタムオブジェクトを返すことです。それもここでもうまくいくはずです。あなたは基本的にlisteningDecoratorを再実装するでしょう。それはAbstractListeningExecutorServiceのまったく些細なラッパーです。それ自体はAbstractExecutorServiceのまったく小さなラッパーです。

2つの合併症が2つあります。 (OK、もっとあるかもしれません。私は私が示唆していたアプローチをテストしていないことを認める。)

  1. AbstractListeningExecutorServiceあなたがnewTaskForを上書きすることはできません。 (なぜ?あなたがfile a feature requestを望むかどうか説明することができます)その結果、AbstractExecutorServiceを直接に拡張し、(短い)AbstractListeningExecutorServiceの実装を大部分は複製する必要があります。
  2. newTaskForListenableFutureも返さなければならず、それもComparableです。 ListenableFutureの具体的な選択はListenableFutureTaskですが、そのクラスはfinalであるため、インスタンスを作成することはできません。Comparable解決方法はとを作成して、を実装するSimpleForwardingListenableFutureに置きます。

なぜ私はあなたがsubmit()はなく​​を扱っていると仮定していますか?

public void testListeningDecorator_noWrapExecuteTask() { 
    ExecutorService delegate = mock(ExecutorService.class); 
    ListeningExecutorService service = listeningDecorator(delegate); 
    Runnable task = new Runnable() { 
    @Override 
    public void run() {} 
    }; 
    service.execute(task); 
    verify(delegate).execute(task); 
} 
を:私はちょうど書いた本試験で示されているよう

listeningDecorator(...).execute()は、入力タスクをラップしません。

関連する問題