6

Guava の ListeningExecutorService は、既存の ExecutorService をラップすることによって実装されるため、execute() メソッドをインターセプトすることによってタスクを「装飾」します。つまり、基になる ExecutorService でカスタム PriorityQueue を使用したい場合、コンパレーターは装飾されたタスクを元のオブジェクトではなく ListenableFutureTask オブジェクトとして「認識」します。

ラップするタスクを把握する方法はありますか? キューのコンパレータがタスクの重みを使用して順序を決定できるようにするには?

4

1 に答える 1

4

submit()ではなく、execute()?に関心があると思います。(私の回答の一番下をご覧ください。)

ListeningExecutorServicefrom (参照するラッパーの種類) を使用MoreExecutors.listeningDecoratorすると、運が悪くなります。listeningDecoratorは、ほとんどの実装と同様に、入力をにExecutorServiceラップします。この問題の通常の解決策は、カスタム オブジェクトを返すように実装およびオーバーライドすることです。ここでもうまくいくはずです。基本的に を再実装します。これは のかなり自明なラッパーであり、それ自体は のかなり自明なラッパーです。submitFutureTaskAbstractExecutorServicenewTaskForlisteningDecoratorAbstractListeningExecutorServiceAbstractExecutorService

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

  1. AbstractListeningExecutorServiceをオーバーライドすることはできませんnewTaskFor(理由は?機能リクエストを提出したい場合は説明できます。) その結果、直接拡張AbstractExecutorServiceAbstractListeningExecutorServiceする必要があり、(短い)実装が大幅に複製されます。
  2. newTaskForも返すListenableFuture必要がありComparableます。a の明らかな選択はListenableFutureですがListenableFutureTask、そのクラスはfinalであるため、インスタンスを作成することはできませんComparable。解決策は、 を作成して、を実装するListenableFutureTaskラップすることSimpleForwardingListenableFutureComparableです。

submit()ではなく、なぜあなたが扱っていると思いますexecute()か?

listeningDecorator(...).execute()私が書いたこのテストで示されているように、入力タスクをラップしません:

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);
}
于 2013-09-25T15:39:00.347 に答える