Lock Striping

Jeonghwa·2023년 1월 23일
0

문제

이전 글 (Collections.synchronizedMap vs ConcurrentHashMap)에서 설명했다싶이, HashMap은 동기화를 지원하지 않는다. 스레드로부터 안전한 데이터 구조가 아니기 때문에, 멀티 스레드(Multi-Thread)환경에서 데이터 불일치가 발생할 수 있다.

이 문제를 극복하기 위해 Collections.syncronizedMap 메서드로 원본 Map을 변환하거나 HashTable 구조를 사용할 수 있다. 둘다 thread-safe하도록 Map인터페이스를 구현하지만, 성능이 저하된다.

이들은 single lock object를 사용하여 데이터 구조에 배타적인 접근을 정의하는 방식 사용하며 이를 대략적인 동기화(coarse-grained synchronization)라고 한다.

아래 그림과 같이 6개의 스레드가 있는 경우, 하나의 스레드만 lock을 획득하고 동기화된 컬렉션에 접근할 수 있다. 스레드들이 서로 다른 버킷의 키에 접근하려는 경우에도 하나의 스레드만 가능하기 때문에 나머지 스레드들은 lock을 얻기 위해 순차적으로 대기한다.


Lock Striping

Lock Striping은 잠금이 여러 버킷(bucket) 또는 스트라이프(stripe)에서 발생하는 기술이다. 즉, 버킷에 액세스 하면 전체 데이터 구조가 아닌 해당 버킷만 잠긴다.

Java에서 Lock Striping의 대표적인 예는 ConcurrentHashMap이다. ConcurrentHashMap은 기본적으로 16개의 버킷을 가지며, 각 버킷마다 자체적으로 lock을 가지고 있기때문에 총 16개의 lock을 가지고 있다. 따라서 별도의 버킷에 있는 키에 액세스하는 스레드는 동시에 접근이 가능하다.

아래 그림을 보면 같은 버킷의 키에 접근하려는 스레드들은 그 중 하나만 접근할 수 있도록 한다. 다른 버킷의 키에 접근하려는 스레드들은 접근이 가능하다. 따라서 Lock Striping방식을 사용한 현재 그림에선 6개 중 3개의 스레드가 동시에 데이터 구조에서 작업을 할 수 있다.

참고 : netjstech - lock stripping in java


실험과 결론

참고로 이 문헌 (baeldung - java lock stripping) 에서는 위 방식의 성능을 비교하기 위해 실험을 한다.
Guava의 Striped라는 클래스를 사용하여 HashMapConcurrentHashMap을 비교하고, 단일잠금(Single Lock)스트라이프 잠금(Striped Lock)을 비교하는 네가지 실험을 수행한다.

Benchmark                                                Mode  Cnt  Score   Error   Units
ConcurrentAccessBenchmark.singleLockConcurrentHashMap   thrpt   10  0,059 ± 0,006  ops/ms
ConcurrentAccessBenchmark.singleLockHashMap             thrpt   10  0,061 ± 0,005  ops/ms
ConcurrentAccessBenchmark.stripedLockConcurrentHashMap  thrpt   10  0,065 ± 0,009  ops/ms
ConcurrentAccessBenchmark.stripedLockHashMap            thrpt   10  0,068 ± 0,008  ops/ms

각 실험은 Map에서 동시 읽기 및 쓰기를 수행하였으며, 결과적으로는 스트라이프 잠금(Striped Lock)을 사용했을 때 HashMapConcurrentHashMap 모두 처리량 점수가 최대 10%의 높은 것을 볼 수 있다.

단일잠금(Single Lock)의 경우 메모리를 적게사용하는 대신 성능을 저하시키지만, 스트라이프 잠금(Striped Lock)의 경우 많은 메모리를 사용하는 대신 작업간의 동시성을 최대화 할 수 있기 때문이다.

참고 : baeldung - java lock stripping

profile
backend-developer🔥

0개의 댓글