由于Guava的ListeningExecutorService是通过包装现有的ExecutorService实现的,因此它通过拦截execute()方法来“装饰”任务。这意味着如果我想在底层ExecutorService上使用自定义PriorityQueue,我的比较器会将装饰任务“看作”为ListenableFutureTask对象而不是原始对象。
有没有办法掌握它包装的任务?这样队列的比较器可以使用任务权重来确定排序吗?
答案 0 :(得分:4)
我认为您关注submit()
而非execute()
? (请参阅我的回复的底部。)
使用ListeningExecutorService
MoreExecutors.listeningDecorator
(你提到的那种包装),你运气不好。与大多数listeningDecorator
实施一样,ExecutorService
会将submit
的任何输入包含在FutureTask
中。此问题的常规解决方案是实现AbstractExecutorService
并覆盖newTaskFor
以返回自定义对象。这也应该在这里工作。你基本上会重新实现listeningDecorator
,这是AbstractListeningExecutorService
的一个相当简单的包装器,它本身就是AbstractExecutorService
的一个相当简单的包装器。
有两对并发症。 (好吧,可能会有更多。我承认我没有测试过我建议的方法。)
AbstractListeningExecutorService
不允许您覆盖newTaskFor
。 (为什么?我可以解释你是否愿意file a feature request。)因此,你必须直接扩展AbstractExecutorService
,在很大程度上复制(短期){ {1}}实施。AbstractListeningExecutorService
必须返回同时为newTaskFor
的{{1}}。 ListenableFuture
的明显选择是Comparable
,但该类为ListenableFuture
,因此您无法创建实例ListenableFutureTask
。解决方案是创建final
和将其包装在实现Comparable
的{{1}} 中。为什么我假设您正在处理ListenableFutureTask
而不是SimpleForwardingListenableFuture
?
Comparable
没有包装输入任务,正如我刚写的这个测试所示:
submit()