2016-08-06 1 views
1

다음 코드는 하나 개의 스레드가 다른 스레드가 이미 업데이트 할 수있는 current 얻을 후Java에서 경쟁 조건없이 원자 변수를 동시에 업데이트하는 것이 가능한 이유는 무엇입니까?

다음
AtomicInteger atomicInt = new AtomicInteger(0); 

ExecutorService executor = Executors.newFixedThreadPool(20); 

IntStream.range(0, 1000) 
    .forEach(i -> executor.submit(atomicInt::incrementAndGet)); 

, 우리는 current 동기화 또는 잠겨 있지 볼 수 있습니다 incrementAndGet

public final int incrementAndGet() { 
    for (;;) { 
     int current = get(); 
     int next = current + 1; 
     if (compareAndSet(current, next)) 
      return next; 
    } 
} 

의 구현 경쟁 조건없이 작동 .

하지만 원자력 클래스가 경쟁 조건을 피하는 것처럼 보입니다.

누군가 내 실수를 지적 할 수 있습니까?

+0

compareAndSet()은 잠금을 사용합니다. 대부분의 구현에서 'compareAndSet()'은 하드웨어에서 잠금을 수행하는 특별한 명령어 (예 : x86 하드웨어의 CMPXCHG 명령어)를 실행합니다. https://en.wikipedia.org/wiki/Compare-and-swap –

답변

3

compareAndSet은 첫 번째 매개 변수가 AtomicInteger의 현재 값과 같은 경우에만 값을 설정하고 true를 반환합니다.

즉, 다른 스레드가 값을 이미 변경 한 경우 current은 현재 값과 같지 않으며 루프가 한 번 더 실행됩니다. 가입일

documentationcompareAndSet(int expect, int update)의 : 원자 주어진 값으로 업데이트되는 경우 전류 값 == 예상되는 값으로 값을 설정

.

관련 문제