[CS/운영체제] 멀티스레드와 동시성 - 22부

황제연·2025년 7월 21일
0

CS학습

목록 보기
142/193
post-thumbnail

멀티스레드 환경에서 CAS연산

멀티스레드 환경에서 CAS 연산도 락을 사용하지 않고, 동시성 문제를 해결할 수 있습니다
CAS를 사용하면 락을 사용하지 않으면서 다른 스레드가 먼저 증가해서
문제가 발생하는 경우에는 do-while 문을 돌며 재시도하는 방식을 사용합니다

연산 동작 방식

  1. 현재 변수의 값을 읽습니다
  2. 변수의 값을 증가시킬 때 원래 값이 같은지 CAS연산을 활용해 확인합니다
  3. 동일하다면 증가된 값을 변수에 저장하고 종료합니다
  4. 동일하지 않다면 다른 스레드가 값을 중간에 변경했기 때문이므로,
    다시 처음부터 반복합니다
    두 스레드가 동시에 실행되면서 발생하는 상황을 스레드가 충돌했다고 표현합니다
    충돌할 때마다 반복해서 다시 시도하므로 결과적으로 락없이 데이터를 안전하게 변경할 수 있습니다

장점

CAS를 사용하는 방식은 스레드 충돌이 드물게 발생하는 환경에서는
락을 사용하지 않기 때문에 보다 더 높은 성능을 발휘할 수 있습니다

락을 사용하는 방식과 비교했을 때, 스레드가 락을 획득하기 위해 대기하지 않기 때문에
대기시간과 오버헤드가 줄어드는 장점이 있습니다

피해야 하는 상황

충돌이 빈번히 발생하는 환경에서는 성능에 문제가 될 수 있습니다
여러 스레드가 동시에 자주 변수값을 변경하려고 시도한다면 CAS는 자주 실패하고 재시도하기 때문에
성능 저하가 발생할 수 있습니다
이 경우에는 반복문을 돌며 CPU 자원을 많이 소모하게 됩니다

CAS(Compare-And-Set)와 락(Lock) 방식 비교

Lock 방식

  • 비관적(pessimistic) 접근법이라고 합니다
  • 데이터에 접근하기 전에 항상 락을 획득합니다
  • 다른 스레드의 접근을 막습니다
  • 다른 스레드가 방해할 것이라고 가정합니다

CAS 방식

  • 낙관적(Optimistic) 접근법이라고 합니다
  • 락을 사용하지 않고 데이터에 바로 접근합니다
  • 충돌이 발생하면 재시도 합니다
  • 대부분의 경우 충돌이 없을 것이라고 가정합니다

정리

충돌이 많이 없는 경우에 CAS 연산이 더 빠르며, 간단한 CPU 연산인 경우 빨리 처리되어서
충돌이 자주 발생하지 않기 때문에 이 경우에 사용하는 것이 적합합니다

예를들어 1000개의 스레드가 모두 락윽 획득하고 반환하는 과정을 거치면,
1000개의 스레드가 순서대로 하나씩 수행되고, 50개의 스레드가 충돌하게 됩니다

하지만 CAS 방식을 사용하면 1000개의 스레드를 모두 한번에 실행하며,
충돌이 나는 50개의 경우만 재시도 합니다

따라서 간단한 CPU연산 작업을 해야한다면 락보다는 CAS 연산을 사용하는 것이 더 효율적입니다

참고

  • 김영한의 실전 자바 - 고급 1편
profile
Software Developer

0개의 댓글