Java Adv 13 - atomic operation - 2
in Programming Language on Java
atomic operation Thread
원자적이지 않은 연산을 멀티스레드 환경에서 실행하면 어떤 문제가 발생하는지 코드로 알아보자. IncrementInteger 는 숫자 값을 하나씩 증가시키는 기능을 제공한다. 예를 들어서 지금까지 접속한 사용자의 수 등을 계산할 때 사용할 수 있다.
1000개의 스레드가 increment 메서드를 호출하여 IncrementInteger 객체의 값을 증가시키도록 한다. 모든 스레드가 종료된 후, 최종 증가된 값을 출력한다. 대기 시간을 두는 이유는 모든 스레드가 동시에 increment()를 호출하면 각 스레드가 접근하는 타이밍이 거의 같아 경쟁 조건이 발생하지 않거나 최소한으로 발생할 수 있다. 그러나 sleep(10)을 추가하면 스레드들이 순차적으로 약간의 시간 차이를 두고 메서드에 접근하게 되면서, 이미 increment() 연산을 진행 중인 다른 스레드와 동시에 겹쳐서 자원에 접근할 가능성이 높아진다.
실행 결과를 보면 기대한 1000이 아니라 다른 숫자가 보인다. 아마도 실행 환경에 따라서 다르겠지만 1000이 아니라 조금 더 적은 숫자가 보일 것이다. 물론 실행 환경에 따라서 1000이 보일 수도 있다. 이 문제는 앞서 설명한 것 처럼 여러 스레드가 동시에 원자적이지 않은 value++ 을 호출했기 때문에 발생한다. 그럼 혹시 volatile 을 적용하면 될까?
Reference
김영한님의 자바 강의