2011-08-03 18 views
0

當任務中斷時,我需要強制釋放資源。爲此,我實施了this solution。但有了這個,當我撥打shutdown()時,ScheduledThreadPoolExecutor.getQueue()中的所有任務都被強制執行,但我的一些工作保留了資源。我很好地檢查了這種行爲,我發現這一點:當任務執行時,他不在ScheduledThreadPoolExecutor隊列中(我知道這聽起來很明顯)。問題是我需要強制釋放所有作業的資源(在隊列中或在執行中)如何獲取在ScheduledThreadPoolExecutor中執行的作業?

那麼,如何獲得正在執行的作業?你有更好的主意嗎?

回答

2

您可以維護提交作業時創建的所有未來的列表。 使用此列表取消所有期貨。

+0

這實際上是我們當前的實現,但是通過該解決方案,我們保留對所有計劃作業(甚至是執行的作業)的引用,因此,引用列表增長很多,需要處理,他們將在內存中,直到調度程序舒tdown長。這會導致垃圾回收問題,你不覺得嗎? – ggarciao

+0

它可能會做,但你只需要保留最後的N期貨。您可以在某個點後取消/放棄期貨。如果系統太落後,你就會遇到一個更復雜的問題。 –

1

難道你想打電話給

executor.shutdownNow() 

,將嘗試取消目前(使用Thread.interrupt所以你需要實現在使用中斷標誌每個任務的「中斷政策」)正在運行的任務。

從javadoc中

嘗試停止所有正在執行的任務,暫停等待任務的處理,並返回等待執行的任務列表。

除了竭盡全力嘗試停止處理主動執行的任務之外,沒有任何保證。例如,典型的實現將通過Thread.interrupt取消,所以任何不能響應中斷的任務都可能永遠不會終止。

這將返回一個等待任務列表,因此您可以始終將其放回「等待列表」,而不是完全鬆開它們。您可能還需要使用「等待終止」來避免代碼被遺漏。例如,executor.awaitTermination(...)

tempus-fugit有一些方便的類來處理這個。您只需致電

shutdown(executor).waitingForShutdown(millis(400)); 

詳情請參閱here

此外,您在博客文章中列出的解決方案;我不確定這是否正確。 Future.cancel只會停止安排任務。如果您要更新博客中的示例以允許中斷(例如cancel(true),它將與shutdownNow等效(或多或少)。也就是說,它將調用interrupt關於下面的任務(如果您已經實施中斷策略)將停止它的處理,至於中斷後的清理,你只需要確保你在中斷策略實現中正確處理,結果是我認爲你可以使用shutdownNow來正確取消清除 (或取消(true))

+0

但'shutdownNow()'方法不會調用預定作業的'Future.cancel()'。實際上,它使用一個私有'Worker'列表通過'Thread.interrupt()'方法中斷線程。所以,我的裝飾器沒有用'shutdownNow()'方法調用。另一方面,你是對的:'shutdown()'方法將在不中斷線程的情況下調用'Future.cancel(false)'。因此,我們實際上做的是在調用'super.shutdownNow()'之前,當參數'mayInterruptIfRunning = true'釋放資源,並覆蓋'shutdownNow()'調用'Future.cancel(true)'。 – ggarciao

+0

問題是:我必須在我的自定義'shutdownNow()'方法中使用哪個作業列表才能正確強制執行所有作業?如果我使用'getQueue()'方法,我會得到預定的和期刊的(如果之前調用shutdown(),這個列表可能是空的)。但是那些實際運行的線程呢? 'shutdownNow()'會中斷它們,但是我怎麼能強制它們釋放它們的資源呢?我需要一個引用來調用'Future.cancel(true)',爲此我保留一個列表,如其他答案中的建議。我不知道這是否是最好的方式 – ggarciao

+0

我想我是說爲什麼要取消所有的電話?你在這裏看到的與中斷有什麼不同? IE瀏覽器。如果您可以在中斷時釋放資源,則可能不需要自定義取消。我認爲探索*不使用取消更多可能是值得的... – Toby

相關問題