2017-02-10 67 views
2

我正在寫一個REST客戶端,它有一個具有固定到期時間的訪問令牌。使用finalize方法作爲Timer的替代方法?

如何確保在過期時間之前請求新令牌?我看到兩個選項:

  1. Timer
  2. 一些有心計與finalize方法可能使用ref package

1)需要我創造條件,在一個給定的時間和要求運行一個新的線程一個新的令牌。這對我來說似乎很浪費。

2)會利用反正會運行的GC線程,所以我不需要創建一個新的線程。當finalize運行時,只檢查令牌是否即將過期,如果是,則請求新的令牌,如果沒有使該對象再次可用,直到下一個GC週期運行。

評論或其他想法?

+4

'GC線程將反正運行'。這可能並非總是如此。 GC只有在需要運行時才由JVM運行。如果您的應用程序有足夠的可用內存,GC可能根本不會被觸發。所以,我建議不要依賴這種方法。 – anacron

+0

每當我有兩個選擇,另一個是「一些詭計」,我總是爲此付出代價。使代碼更有趣⸮ – Kayaman

+0

這就是[⸮](https://en.wikipedia.org/wiki/Irony_punctuation)的原因:) – Kayaman

回答

1

了我的頭,可以通過使用finalize出現問題的頂部:

  • 調試地獄。您取決於GC調用你的方法,你沒有一個適當的參考對象,等等,等等等等
  • 增加不清理正確,因爲你正在使用finalize()創建資源,開拓新的機會連接,而不是關閉並清理它們。
  • GC可能永遠不會被稱爲並且令牌從不更新。
  • 獲取新令牌時可能會出現異常,所以現在您在GC線程中拋出意外的異常 - 不想要。
  • 獲取新標記成功,但無論什麼原因(例如網絡速度較慢)需要很長時間,因此可能會得到java.lang.OutOfMemoryError: GC overhead limit exceeded

創建一個新線程是relatively inexpensive。當然,有更好的方法,但我們在這裏說微秒。你說創建一個新線程「看起來很浪費」,但是,只是想着替代它,you already wasted more time than the overhead caused by creating a new thread every second for the next 40 years

使用計時器。

編輯:或者,更好的是,使用ScheduledExecutorService(見註釋)。

+0

您可能想要添加OP應該考慮使用ScheduledExecutorService作爲其特定用例的比較優勢(即從請求中發生異常) - http://stackoverflow.com/a/409993/3308999 – xTrollxDudex