2011-04-27 55 views
2

我需要使用某種數據結構來存儲掛起的網絡請求。java:用於存儲未決網絡請求的線程安全數據結構(隊列+映射)?

理想情況下,我想隊列也提供地圖訪問,因爲操作基本上如下:

interface PendingRequestStore<K, V> 
{ 
    /* add item to queue with value v and key k */ 
    void add(K k, V v); 
    /* remove and return value of first item in queue, or null if empty */ 
    V pollFirst(); 
    /* return the key of the first item in the queue, or null if empty */ 
    K getFirstKey(); 
    /* get item with key k, or null if absent */ 
    V get(K k);   
    /* remove and return value of item in queue with key k, or null if absent */ 
    V remove(K k); 
} 

的目的是爲了存儲掛起的請求時,他們被髮送出去;那麼,當我得到響應時,我可以使用指定的鍵移除請求。答覆一般不會按請求發出的順序到達。如果我能保證及時回覆,那麼經常使用Map就足夠了,但偶爾也會出現故障,我還需要按照添加到隊列中的順序重新發送孤兒請求。所以我會使用隊列一張地圖,但是當我收到亂序響應時,我需要一種方法來刪除隊列中間的項目。

如果我無法避免同步,那也沒問題,但是也可以使用併發數據結構。

有什麼建議嗎?


:這些鍵沒有順序使一個有序圖如ConcurrentSkipListMap不會幫助我。

+0

查看'java.util.concurrent'包中的集合類。 – 2011-04-27 15:28:48

+0

?哪個?我很熟悉w/j.u.c,並且在這種情況下它們都沒有明顯可用。 – 2011-04-27 15:30:42

+1

舊的LinkedHashMap有什麼問題,Map m = Collections.synchronizedMap(new LinkedHashMap(...))'? – davin 2011-04-27 15:37:36

回答

3

您描述的內容對於未同步的LinkedHashMap看起來非常熟悉,但它提供了排序的概念並將鍵映射到值。

+0

+1。我不知道任何_concurrent_類會在這裏幫助,所以我會回到使用LinkedHashedMap和你自己的同步。getFirstKey()和pollFirst()可以通過(同步)代碼實現:檢查map不是空的;使用迭代器()。next() – 2011-04-27 15:54:11

+0

同意 - 它需要一些自己的代碼封裝 - 出於同步的原因第一和第二提供上述方法。 – Liv 2011-04-27 15:58:14

1

所以我會使用一個隊列和地圖,但隨後 我需要一種方法來去除 中間隊列的項目時,我得到 反應是亂序。

如果您使用LinkedList作爲您的隊列,您可以利用它的remove(Object o)方法。顯然你需要保證地圖和隊列之間的一致性,因此需要進行某種手動同步。

+0

效率是這裏的問題,雖然。 – 2011-04-27 15:48:24

0

你看過java.util.concurrent包,特別是ConcurrentSkipListMap嗎?你只需要定義一個比較器,它將通過插入時間對它們進行排序。 ConcurrentSkipListMap

+0

嗯......這意味着我需要在我的數據中添加時間戳字段;我寧願避免這一點,但你有一點。 – 2011-04-27 15:47:50

+0

或者你可以使用Atomic Long作爲計數器。 – jabbie 2011-05-04 17:32:19