본문 바로가기

프로그래밍/JAVA

함수의 원자성(atomicity) 보장

멀티 쓰레드(multi-thread) 기반의 프로그래밍을 하게 되면 중요한 것이 바로 원자성의 보장이다.

그렇다면 원자성이 무엇인가?

원자성이란 여러개의 쓰레드가 있을 때 특정 시점에 어떤 메소드를 두개 이상의 쓰레드가 동시에 호출 못한다는 것이다.

간단한 예를 들어보자.
class Job implements Runnable {
   public void run() {
      while(true) {
         go();
         stop();
      }
   }
   public void go() {
      /* 매우 중요한 작업이다 */
   }
   public void stop() {
      /* 그냥 일반적인 작업이다. */
   }
}

위의 Job 클래스를 보면 run()메소드에서 go()와 stop()메소드를 무한 호출하고 있다.
그런데 여기에서 go()메소드가 아주 중요한 메소드라고 하자.

메인 클래스에서 Job객체를 이용해서 여러개의 쓰레드를 만들었고, 각 쓰레드를 수행시켰다고 하면 각 쓰레드는 start()메소드를 언제 호출했든지에 상관없이 멀티 쓰레드 정책에 따라 수행될 것이다.

그런데 잘 생각해보면 1번 쓰레드에서 go()메소드를 수행하는 중에 2번 쓰레드가 go()메소드를 수행할 수도 있다.
그렇게 되면 우리가 예상치 못한 문제가 발생할 수 있는 부분이라고 가정하자. (그런 상황은 여러가지 상황이 있을 수 있다. 특히, 서로 다른 쓰레드의 go()메소드에서 같은 변수의 값을 변화시키는 부분일 경우를 생각해 보면 된다.)

어쨌든 go()메소드가 그렇게 중요한 부분이라서 절대로 함수 호출이 끝나기 전에 또 다시 go()메소드가 호출되는 일이 없어야 한다면, 이런 경우가 바로 원자적으로 수행되어야 하는 부분이다.

그래서 이러한 부분을 원자적으로 (atomic) 수행되는 것을 보장해 주는 것이 바로 synchronized 키워드이다. 그래서 go()메소드의 선언 부분을 다음과 같이 바꿔주면 된다.

public synchronized void go()