9

remove()メソッドを使用していますか?同期メソッドがremoveメソッドに追加されていないという記事を読んだ。 ConcurrentHashMapから固有のアイテムを正しく削除するにはどうすればよいですか?Java ConcurrentHashMapから特定の項目を削除します

コード例:

ConcurrentHashMap<String,Integer> storage = new ConcurrentHashMap<String,Integer>(); 
    storage.put("First", 1); 
    storage.put("Second", 2); 
    storage.put("Third",3); 


    //Is this the proper way of removing a specific item from a tread-safe collection? 
    storage.remove("First"); 

    for (Entry<String, Integer> entry : storage.entrySet()) { 
     String key = entry.getKey(); 
     Object value = entry.getValue(); 
     // ... 
     System.out.println(key + " " + value); 
    } 
+0

"私は同期がremoveメソッドに追加されていないという記事を読みました"その記事はJava 5,6,7、または8の時代について書かれていますか?たぶん古いJava版を念頭に置いて書いたのかもしれません。 –

+0

うまくいけば、このリンクはhttp://javarevisited.blogspot.ca/2013/02/concurrenthashmap-in-java-example-tutorial-working.htmlで動作します。彼は「put()、remove()、putAll()、またはclear()のような更新操作は同期していないので、 続きを読む:http://javarevisited.blogspot.com/2013/02/concurrenthashmap-in-java- example-tutorial-working.html#ixzz3OM79B2ol " –

+0

@ peter.petrov - コード例で行ったように、ConcurrentHashMapでremoveメソッドを呼び出すのは問題ありません。スレッド安全性は問題ではありませんか? –

答えて

1

remove方法は、ロックに同期しません。

public V remove(Object key) { 
    int hash = hash(key.hashCode()); 
    return segmentFor(hash).remove(key, hash, null); 
} 

ConcurrentHashMap.Segment#remove(key, hash, null)は次のように定義される:

V remove(Object key, int hash, Object value) { 
    lock(); 
    try { 
     ... 

Javadoc説明:

実際 ConcurrentHashMap#remove()のコードをチェックし、ロックを取得し lockメソッドの呼び出しがあります

検索操作(getを含む)は一般的にブロックされないため、更新操作(たとえば、putおよびremove)。検索は、最新のが完了した更新操作の結果を反映します。 putAllおよびclearなどの集計操作の場合、同時検索では一部のエントリのみの挿入または削除が反映されることがあります。同様に、イテレータと列挙は、イテレータ/列挙の作成時または生成時のある時点でハッシュテーブルの状態を反映する要素を返します。彼らはではないConcurrentModificationExceptionを投げる。ただし、イテレータは一度に1つのスレッドのみが使用するように設計されています。

+0

私のコード例で使用したremoveメソッドは大丈夫ですよね?スレッドセーフについて心配する必要はありませんか? –

+1

はい、問題ありません。スレッドセーフなので、ロックを使用する必要はなく、 'ConcurrentModificationException'も発生しません。 – manouti

+0

@ manouti-おかげでロック、私は私の情報を得た記事をリンクしました。私は著者が間違っていると思います。 –

0

Iterator仕事をする必要があります。

Iterator<Map.Entry<String, Integer>> iterator = storage.entrySet().iterator(); 
while(iterator.hasNext()) 
{ 
    Map.Entry<String, Integer> entry = iterator.next(); 
    if(entry.getKey().equals("First")) 
    { 
     iterator.remove(); 
    } 
} 

リファレンス:https://dzone.com/articles/removing-entries-hashmap

関連する問題