2013-09-24 55 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); 
} 
相關問題