Java의 Hashmap과 ConsherthashMap에 대한 깊은 다이빙
Hashmap은 스레드 안전이 아니며 단일 스레드 환경 또는 외부 동기화에서만 사용해야하며 ConscrerthAshmap은 스레드 안전이며 동시 액세스를 위해 설계되었습니다. 2. Hashmap은 NULL 키와 값을 허용하는 반면, ConsurenTashMap은 NULL을 사용하는 경우 NULLPOINTEREXCEMPLECT를 던집니다. 3. Hashmap은 반복하는 동안 구조 수정에 동시 변형을 던지는 실패한 반복기를 사용하지만 ConsurenThashMap 은이 예외를 던지지 않는 약하게 일관된 반복기를 제공합니다. 4. 내부적으로 Hashmap은 잠금없이 배열 링크 된 목록/트리 구조에 의존하는 반면, ConspernthashMap은 스레드 안전을 위해 세분화 된 버킷 레벨 동기화 및 CAS 작업을 사용합니다. 5. ConsurenThashMap은 잠금이없는 읽기 작업 및 ComputeIfAbsent와 같은 원자 업데이트 방법으로 인해 다중 스레드 시나리오에서 더 나은 확장 성을 제공합니다. 6. 단일 스레드 성능 및 널 지원에 해시 맵을 사용하십시오. 스레드-안전, 캐시 또는 공유 상태 관리와 같은 고 대회 애플리케이션에는 ConcurRenthashMap을 사용하십시오.
Java의 HashMap
및 ConcurrentHashMap
은 Java 응용 프로그램에서 가장 널리 사용되는 MAP 구현 중 하나입니다. 내부 작업, 성능 특성 및 스레드 안전성은 크게 다릅니다. 확장 가능하고 신뢰할 수있는 응용 프로그램을 구축 할 때 이러한 차이를 이해하는 것이 중요합니다.

HashMap
부터 시작하여 ConcurrentHashMap
으로 이동 한 후 마지막으로 주요 영역에서 비교해 보겠습니다.
1. 해시 맵 : 단순성과 속도 (그러나 스레드-안전하지는 않음)
HashMap
은 Java Collections 프레임 워크의 일부이며 기본 해시 테이블 구현을 제공합니다. null
키와 값을 허용하며 이상적인 조건에서 get
및 put
을위한 평균 O (1) 시간 복잡성을 제공합니다.

내부적으로 작동하는 방식
배열 링크 된 목록/트리 구조 :
HashMap
Node
(또는Entry
) 객체를 사용합니다. 각 노드에는 키 값 쌍, 해시 및 다음 노드에 대한 참조 (충돌 처리 용)가 들어 있습니다.-
해싱 :
키의hashCode()
내부 배열에서 인덱스를 계산하는 데 사용됩니다. 두 키에 동일한 해시 (충돌)가 있으면 링크 된 목록을 사용하여 동일한 버킷에 저장됩니다. 충돌 처리 :
버킷이 임계 값 (기본 8)을 넘어 자라고 테이블이 충분히 큰 경우 링크 된 목록은 균형 잡힌 트리 (빨간색 검정 트리)로 변환되어 O (n)에서 O (log n)로 조회 시간을 줄입니다.크기 조정 :
항목 수가 부하 계수 (기본 0.75) × 용량을 초과하면 맵이 크기가 크게 조정되어 버킷 어레이를 연결하고 모든 항목을 다시 해싱합니다. 이것은 비싸고 일시 중지를 유발할 수 있습니다.
주요 제한
- 스레드-안전하지 않음 : 동시 수정은 레이스 조건으로 이어질 수 있습니다.
- 실패 반복자 : 반복 중에지도가 구조적으로 수정되면 (
ConcurrentModificationException
Iterator.remove()
를 통해 제외). - 높은 경합에서 성능 저하 : 외부 동기화없이 접근하는 다중 스레드는 내부 구조를 손상시킬 수 있습니다 (예 : 이전 버전의 크기 조정 중 무한 루프).
⚠️ 동기화없이 다중 스레드 환경에서
HashMap
사용하지 마십시오.
2. ConcurrenthashMap : 스레드-안전 및 확장 가능
Java 5에 도입되었고 Java 8에서 크게 개선 된 ConcurrentHashMap
동시 액세스를 위해 설계되었습니다. 전체 맵을 잠그지 않고 스레드 안전성을 제공하여 여러 독자와 동시 업데이트가 가능합니다.
Java 버전의 진화
- Java 7 : 중고 세그먼트 잠금 - 맵은 각각 자체 자물쇠가있는 세그먼트로 나뉩니다. 이것은 다른 세그먼트에서 동시 쓰기를 허용했습니다.
- Java 8 : 개별 버킷 및 CA (비교 및 스웨이) 작업의
synchronized
블록을 사용하여 세그먼트를 세분화 한 상태로 교체했습니다. 이것은 확장 성을 향상시키고 경합이 감소했습니다.
그것이 동시성을 달성하는 방법
- 잠금 스트립 (Java Pre-Java 8) : 여러 자물쇠가 맵의 다른 부분을 보호합니다.
- 노드 레벨 동기화 (Java 8) : 쓰기 작업 중에 각 버킷을 독립적으로 잠글 수 있습니다.
- CAS 작업 : 원자 업데이트에 사용됩니다 (예 : 버킷에 첫 번째 노드 삽입).
- 나무 쓰레기통 :
HashMap
마찬가지로 양동이는 높은 충돌로 나무가 될 수 있습니다.
스레드 안전 작업
- 모든 작업 (
get
,put
,remove
,compute
등)은 스레드 안전입니다. - 외부 동기화가 필요하지 않습니다.
- 반복자는
ConcurrentModificationException
던지지 않습니다 . 그들은 어느 시점에서지도 상태를 반영합니다 (약하게 일관성).
유용한 동시 방법
Java 8 동시성 하에서 안전한 기능 스타일 방법 :
-
computeIfAbsent(key, mappingFunction)
-
merge(key, value, remappingFunction)
-
forEach(BiConsumer)
이들은 캐싱 시나리오에서 특히 유용합니다.
cache.computeifabsent ( "key", k-> ExpensiveComputation ());
3. Hashmap vs Concurrenthashmap : 주요 차이점
특징 | HashMap | ConcurrentHashMap |
---|---|---|
실 안전 | ❌ 아니요 | ✅ 예 |
동기화 | 매뉴얼 (예 : Collections.synchronizedMap() ) | 내장 |
널 키/값 | ✅ 허용 | ❌ 허용되지 않음 ( NullPointerException 던지기) |
성능 | 단일 스레드 컨텍스트에서 빠르게 | 오버 헤드로 인해 약간 느리지 만 동시성 하에서 더 잘 비늘 |
반복 | 실패 | 약한 ConcurrentModificationException |
내부 잠금 | 없음 | 버킷 레벨 ( synchronized ) CAS |
최고의 사용 사례 | 단일 스레드 또는 외부 동기화 된 시나리오 | 읽기/쓰기 동시성이 높은 다중 스레드 환경 |
4. 언제 어느 것을 사용해야합니까?
HashMap
다음과 같이 사용하십시오.
- 당신은 단일 스레드 컨텍스트에 있습니다.
-
null
키 또는 값을 저장해야합니다. - 스레드에서 공유되지 않은 로컬, 단기 맵을 구축하고 있습니다.
- 성능은 중요하며 동시성은 문제가되지 않습니다.
ConcurrentHashMap
다음과 같이 사용하십시오.
- 여러 스레드가 동시에 읽고 씁니다.
- 외부 동기화없이 높은 처리량이 필요합니다.
- 캐시, 레지스트리 또는 공유 상태를 구현하고 있습니다.
-
computeIfAbsent
와 같은 원자 연산을 사용하려고합니다.
? 이것을하지 마십시오 :
동기화 된 (지도) { if (! map.containskey (key)) { map.put (키, 값); } }이것은 오류가 발생하고 비효율적입니다. 대신 사용하십시오 :
concurrentMap.putifabsent (키, 값);
최종 생각
HashMap
은 간단하고 빠르며 비 콘유트 사용에 적합합니다.ConcurrentHashMap
은 스레드 안전 맵의 선택으로, 너무 많은 성능을 희생하지 않고 동시성과 안전성이 높습니다.- Java 8의 내부 재 설계는 세그먼트 잠금을 제거하고 CAS 및 세밀한 동기화를 수용함으로써
ConcurrentHashMap
더욱 효율적으로 만들었습니다.이러한 맵을 더 깊은 수준으로 이해하면 더 나은 디자인 결정, 특히 고성능 동시 Java 응용 프로그램을 구축 할 때 더 나은 디자인 결정을 내릴 수 있습니다.
기본적으로 스레드에서 맵을 공유하는 경우
ConcurrentHashMap
사용하십시오. 마법은 아니지만 가깝습니다.위 내용은 Java의 Hashmap과 ConsherthashMap에 대한 깊은 다이빙의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undress AI Tool
무료로 이미지를 벗다

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

JDBC 트랜잭션을 올바르게 처리하려면 먼저 자동 커밋 모드를 끄고 여러 작업을 수행 한 다음 결과에 따라 커밋 또는 롤백을 수행해야합니다. 1. 트랜잭션을 시작하려면 Conn.SetAutoCommit (False)에게 전화하십시오. 2. 인서트 및 업데이트와 같은 여러 SQL 작업을 실행합니다. 3. 모든 작업이 성공한 경우 Conn.commit ()에게 전화하여 데이터 일관성을 보장하기 위해 예외가 발생하면 Conn.Rollback ()에게 전화하십시오. 동시에, 재 시도는 리소스를 관리하고, 예외를 올바르게 처리하고, 연결 유출을 피하기 위해 긴밀한 연결을 사용하는 데 사용해야합니다. 또한 연결 풀을 사용하고 부분적으로 롤백을 달성하기 위해 저장 포인트를 설정하고 성능을 향상시키기 위해 거래를 가능한 한 짧게 유지하는 것이 좋습니다.

가상 스레드는 동시성과 IO 집약적 시나리오에서 상당한 성능 이점을 가지고 있지만 테스트 방법과 해당 시나리오에주의를 기울여야합니다. 1. 정확한 테스트는 실제 비즈니스, 특히 IO 차단 시나리오를 시뮬레이션하고 JMH 또는 Gatling과 같은 도구를 사용하여 플랫폼 스레드를 비교해야합니다. 2. 처리량 간격은 분명하며, 일정이 가볍고 효율적이기 때문에 10 만 동시 요청보다 여러 배에서 10 배나 높을 수 있습니다. 3. 테스트 중에, 높은 동시성 수치를 맹목적으로 추구하고, 비 차단 IO 모델에 적응하고, 대기 시간 및 GC와 같은 모니터링 지표에주의를 기울일 필요가있다. 4. 실제 애플리케이션에서는 웹 백엔드, 비동기 작업 처리 및 많은 동시 IO 시나리오에 적합하지만 CPU 집약적 작업은 플랫폼 스레드 또는 포크 플랫폼에 여전히 적합합니다.

TOSETJAVA_HOMEONWINDOWS, FIRSTLOCATETEJDKINSTALLATIONPATH (예 : C : \ ProgramFiles \ java \ jdk-17), thencreateasystemenvaria blenamedjava_homewiththatpath.next, updatePathVariableByadding%java \ _home%\ bin, andverifythesetupusingjava-versionandjavac-v

Servicemesh는 Java Microservice Architecture의 진화를위한 불가피한 선택이며, 그 핵심은 네트워크 논리 및 비즈니스 코드를 분리하는 데 있습니다. 1. Servicemesh는 부하 밸런싱, 퓨즈, 모니터링 및 기타 기능을 부상 에이전트를 통해 처리하여 비즈니스에 중점을 둡니다. 2. Istio Envoy는 중간 및 대형 프로젝트에 적합하며 Linkerd는 가볍고 소규모 시험에 적합합니다. 3. Java 마이크로 서비스는 Feign, Ribbon 및 기타 구성 요소를 닫고 발견 및 의사 소통을 위해 Istiod로 넘겨야합니다. 4. 배치 중 사이드카의 자동 주입을 보장하고 트래픽 규칙 구성, 프로토콜 호환성 및 로그 추적 시스템 구성에주의를 기울이고 점진적인 마이그레이션 및 사전 제어 모니터링 계획을 채택하십시오.

링크 된 목록을 구현하기위한 핵심은 노드 클래스를 정의하고 기본 작업을 구현하는 것입니다. first 데이터 및 다음 노드에 대한 참조를 포함하여 노드 클래스를 만듭니다. linkedlist 클래스를 생성하여 삽입, 삭제 및 인쇄 기능을 구현합니다. hepend 메소드는 꼬리에 노드를 추가하는 데 사용됩니다. printList 메소드는 링크 된 목록의 내용을 출력하는 데 사용됩니다. deletewithValue 메소드는 지정된 값으로 노드를 삭제하고 헤드 노드와 중간 노드의 다른 상황을 처리하는 데 사용됩니다.

서버 측 템플릿 주입 (SSTI) 방지에는 네 가지 측면이 필요합니다. 1. 메소드 호출 비활성화 및 클래스로드 제한과 같은 보안 구성 사용. 2. 템플릿 컨텐츠로서 사용자 입력을 피하고 변수 교체 만 및 입력을 엄격하게 확인하십시오. 3. 자갈, 콧수염 또는 분리 렌더링 컨텍스트와 같은 샌드 박스 환경을 채택합니다. 4. 종속 버전을 정기적으로 업데이트하고 코드 로직을 검토하여 템플릿 엔진이 합리적으로 구성되어 있는지 확인하고 사용자 제어 가능한 템플릿으로 인해 시스템이 공격을 방지하지 못합니다.

Java Collection Framework의 성능을 향상시키기 위해 다음 4 가지 점에서 최적화 할 수 있습니다. 1. Arraylist에 대한 자주 임의의 액세스, 해시 세트에 대한 빠른 검색 및 동의 환경에 대한 동의어 맵과 같은 시나리오에 따라 적절한 유형을 선택하십시오. 2. 용량 확장 오버 헤드를 줄이지 만 메모리 폐기물을 피하기 위해 초기화 중에 용량 및로드 계수를 합리적으로 설정하십시오. 3. 불변의 세트 (예 : List.of ())를 사용하여 보안 및 성능을 향상 시키며 일정한 또는 읽기 전용 데이터에 적합합니다. 4. 메모리 누출을 방지하고 약한 참조 또는 전문 캐시 라이브러리를 사용하여 장기 생존 세트를 관리합니다. 이러한 세부 사항은 프로그램 안정성과 효율성에 큰 영향을 미칩니다.

Pre-FormancetArtUptimeMoryUsage, Quarkusandmicronautleadduetocompile-timeprocessingandgraalvsupport, withquarkusoftenperforminglightbetterine serverless sinarios.2.thyvelopecosyste,
