2013-09-24 56 views
5

由于Guava的ListeningExecutorService是通过包装一个现有的ExecutorService来实现的,它通过拦截execute()方法'装饰'任务。这意味着如果我想在底层ExecutorService上使用自定义的PriorityQueue,我的比较器会将装饰后的任务视为ListenableFutureTask对象而不是原始对象。如何与ListeningExecutorService一起使用PriorityBlockingQueue?

有没有一种方法可以控制它所包装的任务?所以队列的比较器可以使用任务权重来确定排序?

回答

4

我假设你关心的是submit()而不是​​? (请参阅我的回应底部。)

ListeningExecutorServiceMoreExecutors.listeningDecorator(你指的包装类型),你运气不好。与大多数ExecutorService实现一样,listeningDecorator将中的任何输入包装为submit。解决此问题的常规方法是执行AbstractExecutorService并覆盖newTaskFor以返回自定义对象。这也应该在这里工作。你基本上是重新实现listeningDecorator,这是一个相当简单的包装AbstractListeningExecutorService,这本身是一个相当简单的包装AbstractExecutorService

有两个并发症。 (OK,可能有更多的,我承认,我没有测试过我建议的做法。)

  1. AbstractListeningExecutorService不允许您覆盖newTaskFor。 (为什么?我可以解释你是否想要file a feature request。)因此,你必须直接AbstractExecutorService直接,主要是复制(短)AbstractListeningExecutorService实施。
  2. newTaskFor必须返回ListenableFuture这也是ComparableListenableFuture的明显选择是ListenableFutureTask,但该类别为final,因此您无法创建实例Comparable。解决方案是创建一个ListenableFutureTask将其包装在实现ComparableSimpleForwardingListenableFuture中。

为什么我假设你正在处理submit()而非​​?

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); 
} 
相关问题