Tread Safe
라고 하면 멀티 쓰레드 환경에서 여러 쓰레드가 동시에 작업할 시 예상치 못한 결과를 얻게 되는 걸 방지하고자 synchronized
키워드를 사용하여 한 쓰레드씩 접근하도록 하는 방법을 말한다.
컬렉션에도 synchronized
을 적용시켜 안전하게 작업할 수 있도록 한 것들이 있다. 예를 들면 HashTable
같은 것이다.
예를들어 6개의 쓰레드가 작업 중인데 synchronized가 적용된 컬랙션에 접근하면 1개의 쓰레드만 버킷에 접근할 수 있고 나머지 5개의 쓰레드는 대기를 해야 한다. 이렇게 하나의 Lock으로 전체를 관리하여 하나의 쓰레드만 통과시키면 성능이 저하 될 수 밖에 없다.
synchronized을 사용한 컬렉션은 다음과 같은 문제점도 가지고 있다.
put-if-absent같이 데이터가 없는 경우에만 put작업을 할 때 다른 쓰레드가 끼어 들 수 있어서 안전하지 못함.
- 1번 쓰레드가 데이터가 있는지 확인. 작업종료.
- 2번 쓰레드가 작업시작.
- 1번 쓰레드는 데이터 put 작업 못하고 기다리게 됨.
자바에서 대표적으로 Lock Striping
을 적용한 컬렉션은 ConcurrentHashMap
이다. ConcurrentHashMap
은 기본 16개의 Lock을 가지고 있어 별도의 버킷에 접근하는 경우 여러 쓰레드가 동시에 접근 가능하다.
하지만
Lock Striping
은 단일 잠금으로 여러 쓰레드의 접근을 허락하니 전체적으로 잠궈서 독점 엑세스가 필요한 경우에는 더 어렵고 비용이 많이 드는 단점이 있다.
한 줄평 : Synchronize와 Lock Striping 컬랙션을 잘 구분해서 써야겠다.
참고 -
https://www.netjstech.com/2016/05/lock-striping-in-java-concurrency.html