2012-02-27 2 views
4

ConcurrentHashMap의 성능이 저하되기 시작한 ConcurrencyLevel에 대한 최적 값이 있습니까?Java : ConcurrentHashMap의 ConcurrencyLevel 값

그렇다면 그 값은 무엇이며 성능 저하의 원인은 무엇입니까? (이 질문은 ConcurrentHashMap이 가질 수있는 실용적인 한계를 찾으려 노력하지 않음).

답변

4

Javadoc 꽤 상세한 지침을 제공 : 업데이트 작업 중

허용되는 동시성은 내부의 사이즈 설정의 힌트로서 사용되는 옵션 concurrencyLevel 생성자 인수 (디폴트는 16)에 의해 유도된다.

테이블은 내부적으로 분할되어 경쟁없이 지정된 수의 동시 업데이트를 허용하려고 시도합니다. 해시 테이블의 배치는 기본적으로 무작위이므로 실제 동시성은 다양합니다. 이상적으로, 동시에 테이블을 수정할 수있는만큼의 스레드를 수용 할 값을 선택해야합니다. 필요한 것보다 훨씬 더 높은 값을 사용하면 공간과 시간을 낭비 할 수 있으며 값이 상당히 낮 으면 스레드 경합이 발생할 수 있습니다. 그러나 대다수의 등급 내에서 과대 평가 및 과소 평가는 대개 별다른 영향을 미치지 않습니다. 하나의 값은 하나의 스레드 만 수정되고 다른 모든 스레드는 읽는 것으로 알려진 경우에 적합합니다.

요약 : 최적의 값은 예상 동시 업데이트 수에 따라 다릅니다. 그 정도의 값은 잘 작동합니다. 이 범위를 벗어나는 값은 성능 저하로 이어질 수 있습니다.

+0

이 문서를 본 적이 있지만 내 질문에 대답하지 않습니다. ConcurrentHashMap을로드 테스트하려고한다고 가정 해 봅시다. 그렇다면 concurrencyLevel의 성능이 저하되고 왜 시작될까요? – shrini1000

+1

@ shrini1000 : 나는 그것이 실제로 상당히 분명하다고 생각합니다 : 최적의 가치 **는 예상되는 동시 업데이트의 수 **에 달려 있습니다. 크기의 순서 내에서 가치가 잘 작동합니다. Javadoc에 따르면,이 범위를 벗어나는 값은 성능 저하로 이어질 수 있습니다. – NPE

+0

나는 concurrentHashMap이 성능을 저하시키지 않고 취할 수있는 concurrencyLevel의 * max * 값이 무엇인지 다시 말해 보자. (많은 스레드가 동시에 업데이트한다고 가정 해 보자.) – shrini1000

4

당신은 자신에게 두 가지 질문

  • 내가 얼마나 많은 CPU를해야합니까 물어 있나요?
  • 유용한 프로그램이 같은 시간에 몇 퍼센트의 동일한 프로그램을 이용할 수 있습니까?

첫 번째 질문은지도에 한 번에 액세스 할 수있는 최대 스레드 수를 알려줍니다. 10000 개의 스레드를 가질 수 있지만 4 개의 CPU 만 있으면 최대 4 개의 스레드가 동시에 실행됩니다.

두 번째 질문은 해당 스레드가 맵에 액세스하고 유용한 정보를 제공한다는 것을 알려줍니다. 쓸모없는 것을하기 위해지도를 최적화 할 수 있지만 (예 : 마이크로 벤치 마크)이 IMHO에는 포인트 튜닝이 없습니다. 지도를 많이 사용하는 유용한 프로그램이 있다고 가정 해보십시오. 예를 들어 다른 일을하는 데 시간의 90 %를 소비하고있을 수 있습니다. IO, 다른 맵에 액세스, 키 또는 값 작성, 맵에서 가져온 값으로 작업하기.

4 개의 CPU가있는 컴퓨터에서 맵에 액세스하는 데 10 %의 시간을 소비한다고 가정 해보십시오. 이것은 평균적으로 평균 0.4 개의 스레드로 맵에 액세스한다는 것을 의미합니다. (또는 한 스레드가 약 40 %의 시간)이 경우에는 1-4의 동시성 수준이 좋습니다.

어쨌든 마이크로 벤치 마크의 경우에도 동시성 수준을 cpus 수보다 높게 설정하는 것은 불필요합니다.

+0

약 10000 개의 스레드 예 : atmost 4 개의 스레드가 동시에 * 실행할 수 있지만 * 더 많은 스레드가 동시에 액세스 할 수 있습니다 *, 맞습니까? 예 : 쓰레드는 put 또는 put-if-absent 연산의 중간에있는 동안 선매 받는다. 그래서 내 질문은이 다른 유스 케이스에서 더 많은 것이다. – shrini1000

+0

"쓰레드는 풋의 중간에 선매 받는다."어떤 경우에는 쓰레드가 실행되지 않는다. 잠금 장치가 없으므로 효과적으로 액세스 할 수 없습니다. –

+0

cpu에서 실행되지 않는 스레드는 콜렉션에 액세스하는 것으로 간주 할 수 없습니다. –

1

Java 8부터 concurrencyLevel에 대한 ConcurrentHashMap의 생성자 매개 변수는 effectively unused이며 주로 하위 호환성을 유지합니다.구현은 이전 버전의 경우와 같이 고정 된 개수의 세그먼트/스트라이프가 아니라 각 빈에 대한 잠금으로 각 해시 저장소 내의 첫 번째 노드를 사용하도록 다시 작성되었습니다.

요약하면 API 계약에 따라 양수 (0이 아닌 음수가 아닌 값)를 설정하는 경우 Java 8부터는 concurrencyLevel 매개 변수를 설정하는 것에 대해 걱정할 필요가 없습니다.