2013-10-04 3 views
1

나는 AtomicInteger의 유즈 케이스를 잘 알고 있지만 AtomicBoolean이 어떻게 두 개의 액션의 원 자성을 보장 할 수 있는지 혼란 스럽다. '부울 값 변경'및 ii. AtomicBoolean 변수에 대해 자주 인용 사용 사례를 다음에서 '한 번 로직'예 : (초기화)을 실행은 atomicInitialized :AtomicBoolean은 실제로 원 자성을 성취합니까?

if (atomicInitialized.compareAndSet(false, true)) { 
    initialize(); 
} 

먼저 true로 atomicInitialized를 설정 (이 경우는 false)과 의지이 작업 안전하지 않은 intialize()를 실행하십시오. initialize()는 한 번만 호출되지만 getAndSet()을 두 번째로 호출하는 스레드는 첫 번째 스레드가 초기화를 완료 할 때까지 지연되지 않습니다. 따라서, AtomicBoolean은 부울 값을 업데이트 할 때 원 자성을 제공하지만 실제로 'if-block'전체에 대해 원 자성을 제공하지는 않으며 전체 원 자성을 달성하기 위해 동기화/잠금 메커니즘을 사용해야합니다. 따라서 자주 인용되거나 대중적인 유스 케이스가 아닌 것은 원자 적입니다!

+1

http://stackoverflow.com/questions/4501223/when-i-need-to-use-atomicboolean-in-java – JNL

+0

AtomicBoolean은 원자 적이지만 차단하지 않습니다. 이전에 그 예를 보지 못했지만 그래, 깨졌습니다. – kiheru

+0

예. 그 안에 포함 된 부울 값의 값을 처리하는 데는 원 자성 만 제공됩니다 ... "마술처럼"10 선 근처의 모든 것을 원자도 만들 수있는 것은 아닙니다 ... – ppeterka

답변

7

"원자"클래스는 단일 변수에 대해 스레드로부터 안전한 액세스와 조작을 제공하기위한 것입니다. 예를 들어 if 블록과 같은 블록 전체의 동기화를위한 것은 아닙니다. java.util.concurrent.atomic package description에서

:

원자 클래스는 비 블록 데이터 구조 및 관련 인프라 클래스를 구현 을위한 빌딩 블록으로 주로 설계되었습니다. compareAndSet 메서드는 잠금을 대체하지 않습니다. 객체의 중요 업데이트가 인 경우에만 적용됩니다.

전체 블록을 동기화하려면 "원자"클래스에만 의존하지 마십시오. 다른 동기화 코드를 제공해야합니다.

+0

+1 내 대답보다 낫다. – Gray