반응형

자바 원자적 연산
원자적 연산이란?
하나의 연산이 중간에 끊기지 않고 한 번에 수행되는 것
원자적 연산을 사용하는 이유
멀티스레드 환경에서 동시에 여러 스레드가 공유 변수에 접근하면 경합이 발생할 수 있다.
이 문제를 해결하기 위해 synchronized 와 같은 키워드로 lock을 걸어서 동기화 할 수 있지만, 락을 사용하면 성능이 저하될 수 있다.
ex) 아래는 원자적인 연산이 아니여서 경합이 발생할 수 있는 코드이다.
public void use(){
if(i==10){
}
i++;
}
CAS
CAS(Compare-And-Swap) 을 사용해서 동기화 없이(비블로킹, Lock-Free) 원자적 연산을 수행할 수 있도록 설계된 클래스
사용법
import java.util.concurrent.atomic.AtomicInteger;
public class AtomicExample {
public static void main(String[] args) {
AtomicInteger atomicInt = new AtomicInteger(0);
// 값 증가
System.out.println(atomicInt.incrementAndGet()); // 1
// 값 감소
System.out.println(atomicInt.decrementAndGet()); // 0
// 특정 값 더하기
System.out.println(atomicInt.addAndGet(5)); // 5
// 현재 값이 예상한 값(5)과 같으면 10으로 변경
boolean success = atomicInt.compareAndSet(5, 10);
System.out.println(success + " " + atomicInt.get()); // true 10
}
}
핵심 메서드
compareAndSet(expectedValue, newValue) 연산은 다음과 같은 원리로 동작한다.
- 현재 변수의 값이 expectedValue(기대한 값)과 같은지 확인한다.
- 같으면 새로운 값(newValue)으로 변경한다.
- 다르면 아무 작업도 하지 않고 실패한다.

장점과 단점
장점
- 락을 사용하지 않으므로 성능이 좋음 (락 기반 동기화보다 빠름)
- 데드락(Deadlock) 문제 없음
- 멀티스레드 환경에서도 안전하게 동작
단점
- CAS 실패 시 반복(Spin Loop)가 필요해서, 경쟁이 심한 경우 오히려 성능이 저하될 수 있음
- 한 번에 하나의 변수만 갱신 가능 (여러 변수를 동시에 갱신하려면 AtomicReference 또는 StampedLock 같은 방법이 필요)
CAS 실패 시 반복(Spin Loop)가 필요해서, 경쟁이 심한 경우 오히려 성능이 저하될 수 있음에 대해서 더 알아보자면,
import java.util.concurrent.atomic.AtomicInteger;
public class CASExample {
static AtomicInteger atomicInt = new AtomicInteger(0);
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
while (!atomicInt.compareAndSet(0, 1)) {
// 실패하면 계속 시도 (Busy-waiting)
}
System.out.println("Thread 1: 값 변경 완료");
});
Thread t2 = new Thread(() -> {
while (!atomicInt.compareAndSet(0, 2)) {
// 실패하면 계속 시도 (Busy-waiting)
}
System.out.println("Thread 2: 값 변경 완료");
});
t1.start();
t2.start();
}
}
아래와 같이 스핀락이 계속 발생하기 때문에 대기시간이 길수록 성능이 안좋다는 이슈를 가지고 있다.

반응형
'JAVA' 카테고리의 다른 글
태태코딩 - 람다(김영한 실전자바 고급 3편) (1) | 2025.04.27 |
---|---|
태태개발일지 - 고급 java (김영한) 컬랙션 동시성 (1) | 2025.03.19 |
태태개발일지 - java 고급 멀티스레드(김영한) (1) | 2025.03.08 |
태태개발일지 - java 고급 멀티스레드 (1) | 2025.03.06 |
태태개발일지 - 자바 고급 멀티쓰레드(김영한) (1) | 2025.02.22 |