CAS(Compare-And-Swap) 기법

2025. 5. 13. 18:01·SW 공학 & 프로그래밍 언어/Java
728x90
반응형

1. 개요

CAS(Compare-And-Swap)는 동시성 프로그래밍에서 사용되는 원자적 연산 기법이며, CPU 명령 수준에서 제공되는 저수준 동기화 메커니즘

참고!
자바 진영에서 다중 스레드 환경에서 동기화 문제를 해결하기 위한 기법으로, 자바의 Atomic 클래스에서 자주 사용됩니다. CAS는 락을 사용하지 않고도 변수의 일관성을 유지할 수 있도록 하며, 특히 경합이 적은 상황에서 유용하게 사용됩니다.

이 기법은 잠금을 사용하지 않고도 여러 스레드가 동시에 변수를 수정할 수 있도록 도와줍니다.

기본 개념

• CAS 연산은 메모리의 특정 위치에서 현재 값을 읽어와, 기대한 값(expected value)과 비교합니다.
• 만약 현재 값이 기대한 값과 동일하면, 새 값(new value)으로 변경합니다.
• 그렇지 않으면 아무것도 하지 않습니다.

어디에 사용하는가?

  • 락 없이 공유 변수 변경: Lock-Free 알고리즘
  • java.util.concurrent 패키지의 핵심 구성 요소
  • 예) AtomicInteger, ConcurrentHashMap, LongAdder, StampedLock 등

Java 구현

간단한 구현 예시: CAS는 하드웨어 지원이 필요한 원자적 연산이기 때문에, 일반적인 자바 코드로는 완전한 CAS를 구현하기 어렵습니다. 하지만, compareAndSet 메소드를 사용한 예제는 쉽게 구현할 수 있습니다.

CAS는 메모리의 특정 위치에 있는 값을 읽어와, 예상 값과 비교한 후, 예상 값이 일치하면 새로운 값으로 교체하는 방식으로 동작합니다. 자바에서는 AtomicInteger와 같은 클래스를 통해 이 기법이 구현되어 있으며, compareAndSet 메소드를 사용하여 CAS 연산을 수행할 수 있습니다. 이러한 원자적 연산 덕분에, CAS는 동기화 블록을 사용할 필요 없이 스레드 안전한 연산을 수행할 수 있습니다.

import java.util.concurrent.atomic.AtomicInteger;

public class CASExample {
    private AtomicInteger value = new AtomicInteger(0);

    public void compareAndSwap(int expectedValue, int newValue) {
        boolean updated = value.compareAndSet(expectedValue, newValue);
        if (updated) {
            System.out.println("Value updated to " + newValue);
        } else {
            System.out.println("Update failed. Current value is " + value.get());
        }
    }

    public static void main(String[] args) {
        CASExample example = new CASExample();
        
        // Thread 1: Attempts to update value from 0 to 1
        new Thread(() -> example.compareAndSwap(0, 1)).start();
        
        // Thread 2: Attempts to update value from 0 to 2
        new Thread(() -> example.compareAndSwap(0, 2)).start();
    }
}

작동 원리:
• 스레드 1이 compareAndSwap(0, 1)을 호출할 때, 현재 value가 0이면 1로 업데이트됩니다.
• 스레드 2도 동일하게 시도하지만, 스레드 1이 이미 value를 1로 변경했기 때문에 실패하게 됩니다.
• 이처럼 CAS는 성공 여부에 따라 다른 동작을 할 수 있게 해줍니다.


결론

CAS 기법은 락을 사용하지 않기 때문에 병목 현상을 줄일 수 있으며, 경합이 적은 상황에서 뛰어난 성능을 보입니다. 그러나 경합이 심한 환경에서는 반복적인 실패로 인해 오히려 성능이 저하될 수 있으며, 이러한 경우에는 다른 동기화 기법과 함께 사용하거나, 락을 사용하는 방법을 고려해야 합니다.

728x90
반응형
저작자표시 비영리 (새창열림)

'SW 공학 & 프로그래밍 언어 > Java' 카테고리의 다른 글

[Java] -7 % 3? 정수 나눗셈, % 연산, 모듈러의 진실  (3) 2025.06.18
Thread와 대안들  (2) 2025.06.02
[Java] record는 뭐야?  (1) 2025.03.25
REST API에서 요청 DTO를 매번 만들어야 하나?  (0) 2025.03.25
REST API 설계, GET 방식과 보안이슈  (0) 2025.03.25
'SW 공학 & 프로그래밍 언어/Java' 카테고리의 다른 글
  • [Java] -7 % 3? 정수 나눗셈, % 연산, 모듈러의 진실
  • Thread와 대안들
  • [Java] record는 뭐야?
  • REST API에서 요청 DTO를 매번 만들어야 하나?
크크크크
크크크크
공뷰를 합시다.
    반응형
  • 크크크크
    Tom's Note
    크크크크
  • 전체
    오늘
    어제
    • 분류 전체보기 (130)
      • IT 지식 (6)
      • CS (66)
        • 알고리즘 & 자료구조 (19)
        • 운영체제 (41)
        • 네트워크 (1)
        • 데이터베이스 (5)
      • 보안 (6)
      • SW 공학 & 프로그래밍 언어 (5)
        • Java (28)
        • 디자인 패턴 (1)
        • 형상관리 (2)
        • 톰캣(WAS) (2)
        • SW 방법론 (3)
        • 스프링부트 (5)
      • 시스템 설계 (4)
        • Docker (2)
      • 자격증 (2)
  • 블로그 메뉴

    • 링크

    • 공지사항

    • 인기 글

    • 태그

      cifs
      DTO
      리눅스
      문제해결
      1급
      passwd
      단반향
      분석기법
      스프링부트
      whereis
      apropos
      which
      ADsP
      DI
      /etc/passwd
      Chage
      whatis
      2차
      알고리즘
      자바
      암호설정
      docker
      chmod
      REST API
      su
      비트연산
      java
      불변
      usermod
      man
    • 최근 댓글

    • 최근 글

    • 250x250
    • hELLO· Designed By정상우.v4.10.3
    크크크크
    CAS(Compare-And-Swap) 기법
    상단으로

    티스토리툴바