如何将PriorityBlockingQueue与ListeningExecutorService一起使用?

时间:2013-09-24 18:04:39

标签: guava

由于Guava的ListeningExecutorService是通过包装现有的ExecutorService实现的,因此它通过拦截execute()方法来“装饰”任务。这意味着如果我想在底层ExecutorService上使用自定义PriorityQueue,我的比较器会将装饰任务“看作”为ListenableFutureTask对象而不是原始对象。

有没有办法掌握它包装的任务?这样队列的比较器可以使用任务权重来确定排序吗?

1 个答案:

答案 0 :(得分:4)

我认为您关注submit()而非execute()? (请参阅我的回复的底部。)

使用ListeningExecutorService MoreExecutors.listeningDecorator(你提到的那种包装),你运气不好。与大多数listeningDecorator实施一样,ExecutorService会将submit的任何输入包含在FutureTask中。此问题的常规解决方案是实现AbstractExecutorService并覆盖newTaskFor以返回自定义对象。这也应该在这里工作。你基本上会重新实现listeningDecorator,这是AbstractListeningExecutorService的一个相当简单的包装器,它本身就是AbstractExecutorService的一个相当简单的包装器。

有两对并发症。 (好吧,可能会有更多。我承认我没有测试过我建议的方法。)

  1. AbstractListeningExecutorService不允许您覆盖newTaskFor。 (为什么?我可以解释你是否愿意file a feature request。)因此,你必须直接扩展AbstractExecutorService ,在很大程度上复制(短期){ {1}}实施。
  2. AbstractListeningExecutorService必须返回同时为newTaskFor的{​​{1}}。 ListenableFuture的明显选择是Comparable,但该类为ListenableFuture,因此您无法创建实例ListenableFutureTask。解决方案是创建final将其包装在实现Comparable的{​​{1}} 中。

  3. 为什么我假设您正在处理ListenableFutureTask而不是SimpleForwardingListenableFuture

    Comparable没有包装输入任务,正如我刚写的这个测试所示:

    submit()