[Java] AtomicBoolean과 compareAndSet 다시 보기

snowballnote·2026년 9월 21일

PIA 공지 자동 수집에서 사용한 코드.

private final AtomicBoolean collectionRunning =
        new AtomicBoolean(false);

자동 수집이 겹치지 않게 하려고 넣었다.

처음에는 boolean으로 해도 되지 않나 싶었는데
확인하고 값을 바꾸는 작업이 따로 실행되면 동시에 들어온 작업이 둘 다 통과할 수 있다.

if (collectionRunning) {
    return;
}

collectionRunning = true;

그래서 AtomicBoolean의 compareAndSet()을 사용했다.

if (!collectionRunning.compareAndSet(false, true)) {
    log.warn(
            "외부공지 자동 수집 건너뜀: 이전 실행이 아직 진행 중입니다. trigger={}",
            trigger
    );
    return;
}

compareAndSet(false, true)

현재 값이 false일 때만 true로 바꾼다.

성공하면 true
이미 true면 변경하지 않고 false

즉

수집 안 하는 중
→ false
→ compareAndSet(false, true)
→ true로 변경
→ 수집 시작

이미 수집 중이면 이번 실행은 건너뛴다.

수집 끝난 뒤

수집이 끝나면 다시 false로 돌려줘야 한다.

try {
    collectionService.runCollection();
} catch (RuntimeException exception) {
    log.error("외부공지 자동 수집 실패: trigger={}", trigger, exception);
} finally {
    collectionRunning.set(false);
}

오류가 나도 상태를 풀어줘야 하니까 finally에서 처리했다.

범위

이 AtomicBoolean은 ExternalNoticeScheduler 안에 있는 값이다.

그래서 스케줄러 실행끼리 겹치는 건 막을 수 있다.

수동 수집 API는 이 값을 확인하지 않아서
수동 수집과 자동 수집이 동시에 실행되는 것까지 막는 건 아니다.

서버가 여러 대인 경우도 마찬가지로 각 서버마다 값이 따로 있다.

compareAndSet(false, true)
→ false인지 확인하고 true로 바꾸는 걸 한 번에 처리

내 코드에서는 이 정도로 기억해두면 될 것 같다.

profile
개발자로 이 험난한 세상 살아가기

0개의 댓글