由于Guava的ListeningExecutorService是通过包装现有的ExecutorService实现的,因此它通过拦截execute()方法来"装饰"任务.这意味着如果我想在底层ExecutorService上使用自定义PriorityQueue,我的比较器会将装饰任务"看作"为ListenableFutureTask对象而不是原始对象.
有没有办法掌握它包装的任务?这样队列的比较器可以使用任务权重来确定排序吗?
我想你关心的submit()是而不是execute()?(请参阅我的回复底部。)
如果使用ListeningExecutorServicefrom MoreExecutors.listeningDecorator(您所指的包装器类型),您就不走运了。listeningDecorator与大多数ExecutorService实现一样,将所有输入包装submit在FutureTask. 此问题的正常解决方案是实现AbstractExecutorService并重写newTaskFor以返回自定义对象。这在这里也应该起作用。您基本上将重新实现listeningDecorator,这是一个相当简单的包装器AbstractListeningExecutorService,它本身也是一个相当简单的包装器AbstractExecutorService。
有两个并发症。(好吧,可能还有更多。我承认我还没有测试过我建议的方法。)
AbstractListeningExecutorService不允许您覆盖newTaskFor. (为什么?如果您想提交功能请求,我可以解释。)因此,您必须直接扩展AbstractExecutorService,很大程度上重复(简短的)AbstractListeningExecutorService实现。newTaskFor必须返回 a ListenableFuturethat's 也Comparable. a 的明显选择ListenableFuture是ListenableFutureTask,但该类是final,因此您无法创建实例Comparable。解决方案是创建 aListenableFutureTask并将其包装在SimpleForwardingListenableFuture实现Comparable.为什么我假设你正在处理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);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
399 次 |
| 最近记录: |