programing

ConcurrentHashMap이 늘키와 값을 차단하는 이유는 무엇입니까?

goodcopy 2022. 7. 31. 22:01
반응형

ConcurrentHashMap이 늘키와 값을 차단하는 이유는 무엇입니까?

의 JavaDoc은 다음과 같이 말합니다.

맘에 들다Hashtable하지만 와는 달리HashMap, 이 클래스는 허가되지 않습니다.null키 또는 가치로 사용됩니다.

질문: 왜?

두 번째 질문:왜 안 되지?Hashtablenull을 허용하시겠습니까?

데이터 저장에 HashMaps를 많이 사용했습니다.하지만 바꿀 때는ConcurrentHashMap나는 Null Pointer 때문에 여러 번 곤경에 처했다.예외입니다.

저자(Doug Lea)로부터:

ConcurrentMaps(ConcurrentHashMaps, ConcurrentSkipListMaps)에서 null이 허용되지 않는 주된 이유는 비동시 맵에서 거의 허용할 수 없는 애매함을 수용할 수 없기 때문입니다.중요한 것은 만약의 경우이다.map.get(key)돌아온다null키가 명시적으로 에 매핑되는지 여부를 검출할 수 없습니다.nullvs 키가 매핑되지 않았습니다.비동시 맵에서는 다음 방법으로 확인할 수 있습니다.map.contains(key)단, 동시에 콜간에 맵이 변경되었을 가능성이 있습니다.

적어도 부분적으로는 이 두 가지를 합쳐서containsKey그리고.get단일 통화로 변환합니다.맵이 늘을 유지할 수 있는 경우 맵이 null인지 아닌지는 알 수 없습니다.get는 해당 값에 대한 키가 없거나 값이 늘이기 때문에 늘을 반환하고 있습니다.

그게 왜 문제죠?왜냐하면 스스로 그것을 할 수 있는 안전한 방법은 없기 때문이다.다음 코드를 사용합니다.

if (m.containsKey(k)) {
   return m.get(k);
} else {
   throw new KeyNotPresentException();
}

부터m동시 맵입니다.키 k를 삭제할 수 있습니다.containsKey그리고.get이 스니펫에 의해 테이블에 존재하지 않는 늘이 반환됩니다.KeyNotPresentException.

보통은 동기화하는 것으로 해결되지만 동시 맵에서는 물론 동작하지 않습니다.따라서 의 시그니처는get변경할 필요가 있었습니다.이러한 변경 방법은 사용자가 처음부터 늘 값을 삽입하지 않도록 하고, 그것을 계속 "키를 찾을 수 없습니다"의 자리 표시자로 사용하는 것뿐입니다.

Josh Bloch가 디자인한HashMap; Doug Lea 설계ConcurrentHashMap명예훼손이 아니길 바랍니다실제로 null이 초기화되지 않은 것을 나타낼 수 있도록 null은 랩핑이 필요한 경우가 많다는 것이 문제라고 생각합니다.클라이언트 코드가 null을 필요로 하는 경우 null을 래핑하는 데 드는 (인정적으로 적은) 비용을 지불할 수 있습니다.

null에서는 동기화할 수 없습니다.

편집: 이 경우에는 이러한 이유로 인한 것이 아닙니다.처음에는 동시 업데이트에 대해 무언가를 잠그거나 오브젝트 모니터를 사용하여 무언가를 수정했는지 여부를 감지하는 데 뭔가 멋진 일이 벌어지고 있다고 생각했지만 소스 코드를 조사해보니 잘못된 것 같습니다. 즉, 해시의 비트마스크를 기반으로 한 "세그먼트"를 사용하여 잠깁니다.

이 경우 해시테이블을 복사하기 위해 한 것이 아닐까 생각합니다.해시테이블은 릴레이셔널 데이터베이스 월드에서는 null!=null이기 때문에 null을 키로 사용하는 것은 의미가 없기 때문에 그렇게 한 것이 아닐까 생각합니다.

API 문서의 다음 단편은 "이 클래스는 스레드의 안전성에 의존하지만 동기화 세부 사항은 의존하지 않는 프로그램에서 해시테이블과 완전히 상호 운용할 수 있습니다."라는 좋은 힌트를 줄 것입니다.

아마도 그들은 단지 그 일을ConcurrentHashMap와 완전히 호환성이 있는/교환 가능한Hashtable그리고.Hashtable에서는 늘 키와 값을 사용할 수 없습니다.

ConcurrentHashMap은 스레드 세이프입니다.null 키와 값을 허용하지 않는 것은 스레드 세이프를 확보하기 위한 일부라고 생각합니다.

null 값을 허용하지 않는 것은 올바른 선택이라고 생각하지 않습니다.대부분의 경우 null 값을 가진 키를 con-current map에 넣습니다.단, Concurrent Hash Map을 사용하면 할 수 없습니다.향후의 JDK 버전에서는, 그것을 서포트할 수 있는 것을 추천합니다.

언급URL : https://stackoverflow.com/questions/698638/why-does-concurrenthashmap-prevent-null-keys-and-values

반응형