2013-09-01 52 views
2

我有一個Android應用程序,其核心組件是HashMap<String,float[]>. 該系統具有較高的併發性。 e.g 這裏有以下三種情況下,我都經常發生,他們是通過HashMap的所有鍵在本質上高效使用ConcurrentHashMap?

  1. 迭代高度重疊,並做 它的值(只讀操作)一些操作。
  2. 在Hashmap中添加新的鍵值對。
  3. 從哈希圖中刪除某些密鑰。

我做的所有這些操作在不同的線程,從而正在使用的ConcurrentHashMap ,因爲在檢索一些不一致事犯規。例如迭代地圖時,如果添加了新條目,那麼不必立即讀入這些新值,因爲我確保下次讀取這些新值。

而且同時去除的條目,我重新創建迭代器每次以避免「ConcurrentModificationException的」

假設,有以下的HashMap(即一個ConcurrentHashMap)

ConcurrentHashMap<String,float[]> test=new ConcurrentHashMap<String, float[]>(200); 

現在對於檢索我做以下

Iterator<String> reader=test.keySet().iterator(); 
      while(reader.hasNext()) 
      { 
       String s=reader.next(); 
       float[] temp=test.get(s); 
       //do some operation with float[] temp here(read only operation) 
      } 

和去除我下面

boolean temp = true; 
     while (temp) { 
      for (String key : test.keySet()) { 
       temp = false; 
       if (key.contains("abc")) { 
        test.remove(key); 
        temp = true; 
        break; 
       } 
      } 
     } 

,並在新值插入時,我只是做

test.put("temp value", new float[10]); 

我不知道,如果它是一個非常有效的利用。另外,不要讀取已刪除的值(但是我需要效率,並且由於在函數調用期間再次創建了迭代器,它保證了在下次我不會獲取刪除的值),因此可能會產生很多不一致容忍?

請問有人能告訴我一個有效的方法嗎?

PS。我忘了提到爲什麼我以這種方式進行清除操作。 我現在已經改變了上其從等於刪除,包含(有可能是具有前綴「ABC」,然後不同的後綴多刺的條件。所以我需要刪除所有這些呢。

+0

迭代整個地圖以刪除一個條目肯定效率不高。你爲什麼不直接調用remove(「abc」)? – EJP

+0

是的,哎呀,我現在已經將刪除條件更改爲包含.. –

+0

不,您應該將整個塊更改爲只需一次調用remove()。你不需要別的東西,我不明白你爲什麼會這麼想。 -1 – EJP

回答

4

迭代和做對其值進行一些操作(只讀操作)。

不要過度按鍵迭代到那麼太檢索值 - 迭代直接設置條目:

for (Map.Entry<String, float[]> e : map.entrySet() { 
    String key = e.getKey(); 
    float[] value = e.getValue(); 
    //do something with them 
} 

這是一般的(甚至是「正常」包含HashMap)更有效,但它也會減少你的情況下的爭用(訪問地圖的一半)。

在哈希表中添加新的鍵值對。

是的,它很簡單:map.put(s, f);

從HashMap中刪除某些鍵。

如果您需要檢查關鍵字包含給定的字符串,那麼你就需要遍歷喜歡自己正在做的鑰匙,雖然我不知道爲什麼你有一段時間+爲突破,而不是一個簡單的。

+0

好吧..所以遍歷入口集總是更快?即使進行拆除操作,我也這麼做嗎? –

+1

@DebarshiDutta不,如果您需要同時訪問鍵和值,速度會更快 - 如果您只關心鍵(就像在刪除中一樣),那麼迭代keySet會更有效。 – assylias

+0

@ user1084563我不知道 - 謝謝。 – assylias

2

,因爲路您正在使用的ConcurrentHashMap,你恰恰刪除其Concurrent特點。你在嘗試(重新)同步將工作得非常頻繁,但並非總是如此。

你有沒有考慮過離開keysHashMap?我想類似的東西:

public static final float[] DELETED= new float[0] ; 

    /* delete */ 
    test.put(key,DELETED); 

    /* insert */ 
    test.put(key,value); 

    /* iterate */ 
    for(Map.Entry<String,float[]> e: test.entrySet) { 
     if(e.getValue() != DELETED) { 
      operateOn(e); 
     } 
    } 

如果鍵太易變(即,過了一段時間你會有太多DELETED項目),那麼你可以創建一個清理Thread

0

根據ConcurrentHashMap API,它的迭代器不會拋出ConcurrentModificationException,因此在刪除後不需要中斷。但在任何情況下,迭代和刪除正確的方法是這樣的

for (Iterator<String> i = test.keySet().iterator(); i.hasNext();) { 
    String next = i.next(); 
    if (next.equals("abc")) { 
      i.remove(); 
    } 
} 

這樣它會工作,即使通過所有的鍵在HashMap中快速失敗的迭代器不ConcurrentModificationException的

+0

好的..我沒有看它然後..我會改變那 –

+0

爲什麼?調用remove()方法有什麼問題? – EJP