2011-05-29 78 views
6

G'day everyone,Java:一個延時隊列

我有一個系統(源),需要在某些對象發生變化時異步通知另一個系統(目標)。原因在於源系統可能在很短的時間間隔內多次改變單個對象(更新非常「突然」),在這種情況下,僅僅通知目標系統一次,並且最終狀態目的。

我的想法是在ThreadPoolExecutor前面使用某種時間延遲的去重排隊。這個隊列將:

  1. 保持在隊列項的最小時間量(理想配置爲只是一個smidgin長於突變的典型突發的持續時間)

  2. 替換現有的對象如果重複(由對象的標識符定義)被排隊。但是,該項目應該保留其在隊列中的原始位置(以避免任何一個項目被永久性地碰到隊列的後面 - 在某些時候,我們只需要發送通知,即使另一個項目會立刻出現)。

我在java.util中沒有看到任何完全一樣的東西,而且我在這個領域的google-fu看起來特別弱。

有沒有人執行過此操作,知道一個BlockingQueue實現的行爲如此,或者有關於如何實現一個的提示?

在此先感謝!

Peter

PS。我知道ESB會這樣做,但在這種情況下,這太重量級了 - 理想情況下,我不想將任何新的庫依賴項添加到源系統中。

回答

4

我認爲您最好的選擇是延長ArrayBlockingQueue並覆蓋offerpoll以添加時間延遲功能。 特別是ArrayBlockingQueue,因爲它有一個contains方法。

另一個想法是DelayQueue您可以覆蓋offer刪除舊元素並插入新元素,但保留舊的時間延遲,這將基本上保持順序。 然後,您需要將您的隊列項目包裝在Delayed界面中。

+0

謝謝trutheality。有關直接實現'BlockingQueue'的任何想法,但委託給一個內部的'ArrayBlockingQueue'實例,在'offer'和'poll'方法中有一些額外的邏輯?我總是對擴展核心JDK類有點懷疑 - 其中很多都沒有真正設計過(特別是在java.util.concurrent中,從我那裏有限的捅破)。 – Peter 2011-05-29 06:41:34

+0

那麼在這種情況下,擴展和執行+內部之間的區別是使用'this' /'super'和'myBlockingQueue'作爲隊列對象的區別,所以這是一個品味IMO的問題。 – trutheality 2011-05-29 06:50:08

+0

現在我想到了,'DelayQueue'的想法可能會更容易。我認爲最棘手的部分是在隊列中更新隊列元素,如果你使用'ArrayBlockingQueue',可能會涉及到一個'iterator'或者像' ArrayList的引用以方便訪問對象。使用'DelayQueue'只需'remove',匹配到期時間和'offer'。 – trutheality 2011-05-29 06:58:59

0

您可以僅通知系統發生更改,並讓其他系統獲取新狀態。然後在獲取狀態之前不要通知進一步的變化。

+0

感謝Software Monkey,但我認爲這會將原始問題轉換爲更大的問題 - 即必須跟蹤潛在的數百萬個對象的單個「檢索狀態」。 – Peter 2011-05-29 06:44:56