2013-01-14 18 views
0

我有一個ExecutorService(或atm的子類ThreadPoolExecutorService),我將任務傳遞給submit(Runnable r)ExecutorService.submit,等待已安排的類似實例

有時候同樣的任務會在它仍在運行的時候被重新提交,然後我想第二次提交等待第一個完成。即排隊。如何才能做到這一點?只有提交的任務已經運行,它才應該排隊,否則應該直接執行。

返回的Future<> s將用於有時取消任務。

類似這樣;

Runnable r = new LengthyRunnable(); 

    Future<?> f1 = submit(r); //should start to run 
    Future<?> f2 = submit(r); //should be queued and wait for f1 
    Future<?> f3 = submit(r); //in case f1 hasnt finished, and f2 is queued, should remove f2 from the queue and take it's place 

我已經子類ThreadPoolExecutorService,我usind beforeExecute和afterExecute跟蹤的任務,但它變得困難......我應該用其他的東西再ThreadPoolExecutorService

回答

0

我會做LengthyRunnable重複任務(用合適的池間隔),檢查是否需要再次運行。這樣可以確保它不會多次運行。

0

當f3入隊時,您想要移除入隊的f2任務。廣告f2尚未開始。但是,由於底層實現可能不是異步的,因此ExecutorService不會公開對隊列的訪問。 ThreadPoolExecutor的有underlyign隊列中,但實際上並沒有將其暴露:)

如果你不想只是做一個調度/複發性的任務,因爲有人建議可能比你考慮下。

創建一個WorkPerformer Runnable。傳遞一些BlockingQueue,即LinkedBlockingQueue。該隊列將用於排隊某種需要執行的LongyTask。

在調用代碼中,您將創建一個可以查看隊列的同步塊 - 如果f2在那裏並且f1仍在運行(WorkPerformer會有某種同步標誌),您將使f2出隊併入隊f3。

很難提出什麼更/更好不知道這背後的意圖是。