
원자적 연산은 더 이상 나눌 수 없는 단위로 수행되는 연산을 의미. 중단되지 않고 다른 연산과 간섭 없이 완전히 실행되거나 전혀 실행되지 않는 성질을 가지고 있다.
예를 들어, 다음 연산은 원자적 연산이다.
int i = 10;
i = 1; // 원자적 연산
하지만 다음 연산은 원자적 연산이 아니다.
i = i + 1; // 원자적 연산이 아님
원자적 연산이 아닌 이유는 다음의 단계로 연산이 실행되기 때문이다.
i 의값을읽는다. i 의 값을 10이라고 가정 해 본다.i 변수에 대입한다.CAS(Compare-And-Swap)는 락을 사용하지 않고도 원자적 연산을 수행할 수 있는 기법이다. 이는 동기화의 비용을 줄이고 성능을 향상시키기 위해 사용된다. 자바에서는 AtomicInteger, AtomicBoolean과 같이 Atomic이라는 이름이 붙은 클래스를 통해 CAS를 지원하며, 동시성과 관련되어 구현된 코드에서 최적화를 위한 기법으로 CAS를 사용하는 경우가 있다.
CAS 연산은 현재 값과 기대 값을 비교하여 일치하면 새로운 값으로 교체하는 연산. 예를 들어, AtomicInteger를 사용한 CAS 연산은 다음과 같다
AtomicInteger atomicInteger = new AtomicInteger(0);
boolean result = atomicInteger.compareAndSet(0, 1); // 현재 값이 0이면 1로 변경
이와 같은 CAS연산을 통하면, CPU에서 원자적연산으로 처리하는 결과를 갖는다. (즉 원자적 연산이 된다)
CAS는 충돌 가능성이 낮은 환경에서 매우 효율적이다. 예를 들어, 주문 수를 증가시키는 단순한 연산에서 CAS를 사용하면, 충돌이 발생할 가능성이 매우 낮기 때문에 높은 성능을 발휘할 수 있다. 그러나 데이터베이스 결과를 기다리거나 다른 서버의 요청을 기다리는 것처럼 오래 기다리는 작업에서는 락을 사용하는 것이 더 적절하다.
이 CAS 연산에 대한 별도의 예시 코드는 정리 하지 않는다. 왜냐하면 직접 구현해서 사용하는 경우는 없기 때문이다. Atomic{xxx}와 같이 CAS 연산을 사용하는 라이브러리의 내부구현에 대한 기초적인 개념적 이해와 이런 CAS 연산을 사용하는 라이브러리들을 잘 사용하는 정도면 충분하기 때문이다.