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

황제연·2025년 7월 19일
0

CS학습

목록 보기
140/193
post-thumbnail

락 기반 방식의 문제점

락은 공유 자원을 보호하기 위해 공유 자원에 대해 접근하는 것을 제한합니다

락이 걸려있으면 다른 스레드가 자원에 접근할 수 없고 락이 해제될 때까지 대기해야합니다
그리고 이 과정에서 락을 획득하고 해제하는데 시간이 발생합니다
이 과정이 반복된다면 성능이 저하되는 문제가 발생할 수 있습니다

CAS

이런 문제를 해결하려고 락을 걸지 않고 원자적인 연산을 수행하는 방법이 바로
CAS(Compare-And Swap, Compare-And-Set)연산이라고 합니다

락을 사용하지 않는 방법이기 때문에 lock-free 기법이라고도 합니다
CAS는 락을 완전히 대체하지는 않고, 작은 단위의 일부 영역에 적용할 수 있습니다

따라서 Default는 락을 사용하고, 특별한 경우에는 CAS를 적용할 수 있습니다

public class Main{
	public static void main(String[] args){
		AtomicInteger = atomic = new AtomicInteger(0);
		System.out.println(atomic.get());
		System.out.println(atomic.compareAndSet(0,1) + " " +atomicInteger.get());
		System.out.println(atomic.compareAndSet(0,1) + " " +atomicInteger.get());
	}
}

위와 같은 코드 예제의 출력 결과는 0 , true 1, false 1입니다
atomic변수가 가지고 있는 값이 현재 0이라면 값을 1로 바꾸라는 명령어로 처음은 변경되었지만
이후에는 변경된 이후의 값인 1으로 있기 때문에 false가 출력되었습니다

여기서 해당 메소드는 원자적으로 실행되며, 이 기능이 바로 CAS 연산입니다

예제 분석

그렇다면 이 연산은 어떻게 이루어져있을까요?
atomic.compareAndSet(0,1)은 2개로 나누어진 명령어입니다
1. 메인 메모리에 있는 값을 확인합니다
2. 기대하는 값이 0이 아니면 원하는 값인 1로 변경합니다

CPU 하드웨어 지원

CAS연산은 위와같이 원자적이지 않은 두 연산을 CPU 하드웨어에서 하나의 원자적인 연산으로
묶어서 제공하는 기능입니다

소프트웨어가 제공하는 기능이 아니라 하드웨어가 제공하는 기능입니다
CPU는 위 과정 두개를 하나로 묶어서 하나의 원자적인 명령으로 만들어버립니다
그렇기 때문에 중간에 다른 스레드가 개입할 수 없습니다

그렇기 때문에 처음 atomic.compareAndSet(0,1)은 성공했으나,
두번째 atomic.compareAndSet(0,1)은 실패한 것을 확인할 수 있습니다!

참고

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

0개의 댓글