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 메소드에 추가되지 않은 기사를 읽었습니다"이었다 그 기사는 자바 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 메서드를 호출하면 괜찮습니까? thread-safety는 문제가되지 않아야합니까? –

답변

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 포함)은 일반적으로 차단하지 않으므로 업데이트 작업 (예 : putremove). 검색 결과는 가장 최근에 완료된 업데이트 작업이 시작될 때의 결과를 반영합니다. putAllclear과 같은 집계 연산의 경우 동시 검색은 일부 항목의 삽입 또는 제거를 반영 할 수 있습니다. 마찬가지로 반복자와 열거 형은 반복자/열거 형을 만들 때 또는 생성 한 시점에서 해시 테이블의 상태를 반영하는 요소를 반환합니다. 그들은 이 아니며ConcurrentModificationException입니다. 그러나 이터레이터는 한 번에 하나의 스레드에서만 사용하도록 설계되었습니다.

+0

코드 예제에서 사용한 제거 메서드는 괜찮습니다. 맞습니까? 스레드 안전성에 대해 걱정할 필요가 없습니다. –

+1

네, 괜찮습니다. 사용에 락이 필요 없게되어, ConcurrentModificationException가 발생하지 않는 점이 thread로부터 안전합니다. – 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