Java Adv 15 - CAS operation - 1
in Programming Language on Java
락 기반 방식의 문제점
SyncInteger 와 같은 클래스는 데이터를 보호하기 위해 락을 사용한다. 여기서 말하는 락은 synchronized , Lock(ReentrantLock) 등을 사용하는 것을 말한다. 락은 특정 자원을 보호하기 위해 스레드가 해당 자원에 대한 접근하는 것을 제한한다. 락이 걸려 있는 동안 다른 스레드들은 해당 자원에 접근할 수 없고, 락이 해제될 때까지 대기해야 한다. 또한 락 기반 접근에서는 락을 획득하고 해제하는 데 시간이 소요된다. 예를 들어서 락을 사용하는 연산이 있다고 가정하자. 락을 사용하는 방식은 다음과 같이 작동한다.
- 락이 있는지 확인한다.
- 락을 획득하고 임계 영역에 들어간다.
- 작업을 수행한다.
- 락을 반납한다.
여기서 락을 획득하고 반납하는 과정이 계속 반복된다. 10000번의 연산이 있다면 10000번의 연산 모두 같은 과정을 반복한다. 이렇듯 락을 사용하는 방식은 직관적이지만 상대적으로 무거운 방식이다.
CAS
이런 문제를 해결하기 위해 락을 걸지 않고 원자적인 연산을 수행할 수 있는 방법이 있는데, 이것을 CAS(Compare-And-Swap, Compare-And-Set) 연산이라 한다. 이 방법은 락을 사용하지 않기 때문에 락 프리(lock-free) 기법이라한다. 참고로 CAS 연산은 락을 완전히 대체하는 것은 아니고, 작은 단위의 일부 영역에 적용할 수 있다. 기본은 락을 사용하고, 특별한 경우에 CAS를 적용할 수 있다고 생각하면 된다.
compareAndSet(0, 1)
atomicInteger 가 가지고 있는 값이 현재 0이면 이 값을 1로 변경하라는 매우 단순한 메서드이다. 만약 atomicInteger 의 값이 현재 0이라면 atomicInteger 의 값은 1로 변경된다. 이 경우 true 를 반환한다. 만약 atomicInteger 의 값이 현재 0이 아니라면 atomicInteger 의 값은 변경되지 않는다. 이 경우false 를 반환한다. 여기서 가장 중요한 내용이 있는데, **이 메서드는 원자적으로 실행**된다는 점이다. 그리고 이 메서드가 제공하는 기능이 바로 CAS(compareAndSet) 연산이다.
Reference
김영한님의 자바 강의