ConcurrentHashMap을 사용할 때 일부 동기화 블록을 코드에 추가해야 할 때를 알아야합니다. 다음과 같은 방법이 있다고 가정 해 보겠습니다.ConcurrentHashMap의 추가 동기화는 언제 어떻게 사용해야합니까?
private static final ConcurrentMap<String, MyObjectWrapper> myObjectsCache = new ConcurrentHashMap<>(CACHE_INITIAL_CAPACITY);
public List<MyObject> aMethod(List<String> ids, boolean b) {
List<MyObject> result = new ArrayList<>(ids.size());
for (String id : ids) {
if (id == null) {
continue;
}
MyObjectWrapper myObjectWrapper = myObjectsCache.get(id);
if (myObjectWrapper == null) {
continue;
}
if (myObjectWrapper.getObject() instanceof MyObjectSub) {
((MyObjectSub) myObjectWrapper.getObject()).clearAField();
myObjectWrapper.getObject().setTime(System.currentTimeMillis());
}
result.add(myObjectWrapper.getObject());
if (b) {
final MyObject obj = new MyObject(myObjectWrapper.getObject());
addObjectToDb(obj);
}
}
return result;
}
효율적으로이 방법을 어떻게 만들어야합니까? "get"은 안전하지만 일단 캐시에서 값을 가져 와서 캐시 된 객체의 필드를 업데이트하면 다른 스레드가 동일한 래퍼를 가져 와서 동일한 기본 객체를 업데이트하려고 할 때 문제가 발생할 수 있습니다. 동기화를 추가 하시겠습니까? 그렇다면 "get"에서 루프 반복 또는 전체 루프의 끝까지 동기화해야합니까? 좀 더 작업 등 루프 내부의지도 키/값을 수행해야 할 때
아마 누군가가
정말 감사하겠습니다 ... ConcurrentHashMap의의 적절하고 효율적으로 사용의 좀 더 구체적인 가이드 라인을 공유 할 수 있습니다.
편집 : 질문에 대한 몇 가지 상황 : 나는 현재 생산 코드의 일부 DAO 클래스의 리팩토링에 일하고 있어요 및 데이터베이스에서 검색 데이터를 캐싱 HashMaps을 사용하는 클래스의 몇 가지. 캐시를 사용하는 모든 메소드 (쓰기 또는 읽기 용)는 동기화 된 (캐시) 블록 내에 전체 내용을 담고있었습니다 (안전한 것으로?). 동시성에 대한 많은 경험이 없기 때문에이 기회를 통해 배우고 싶습니다. 순진하게 HashMaps를 ConcurrentHashMaps로 변경했으며, 이제는 필요한 곳에 동기화 된 블럭을 제거하려고합니다. 모든 캐시는 쓰기 및 읽기에 사용됩니다. 제시된 방법은 내가 변경 한 방법 중 하나를 기반으로하고 있으며 지금은 언제 그리고 어느 정도 동기화를 배우려고합니다. 메소드 clearAField는 랩핑 된 POJO 오브젝트의 필드 중 하나의 값을 변경하고 addObjectToDb는 오브젝트를 데이터베이스에 추가하려고 시도합니다.
다른 예는 캐시의 보충 될 것이다 :
public void findAll() throws SQLException{
// get data from database into a list
List<Data> data=getAllDataFromDatabase();
cacheCHM.clear();
cacheCHM.putAll(data);
}
하는 경우 I는 동기화 (cacheCHM) 블록 내부의 명확하고 putAll에 넣어해야, 오른쪽?
내가 찾을 일부 게시물을 읽으려고했습니다/기타 루프가없는 단일 작업과 CHM의 적절하고 효율적으로 사용할 수 있지만, 대부분의 거래에 대한 기사는 .... 내가 찾은 가장은 다음과 같습니다 http://www.javamadesoeasy.com/2015/04/concurrenthashmap-in-java.html
꽤 많이 당신이 응용 프로그램 논리에 따라 달라집니다. – pintxo
검색 값을 스레드로부터 안전하도록 업데이트해야하는 경우 개체 자체에서 동기화해야합니다. 'ConcurrentHashMap'은 포함 된 값이 아닌 맵 자체의 구조 (즉, 키와 값의 관계)만을 보호합니다. –
@Jim에 동의합니다. 동시 맵은 구조 만 보호합니다 (예 : 키와 값의 관계). 위의 코드 컨텍스트에 따라 하나만 더 추가하고 싶습니다. 즉, ie.e myObjectsCache.get (id) 값을 읽는 것입니다.이 목적을 위해 호출 할 때까지 동시 맵이 필요하지 않을 수도 있습니다. map.put(). – pbajpai21