2017년 4월 20일 목요일

[java] volatile이란 뭘까?

Dzone에서 volatile내용을 보고 있다가 좀 적어놔야 할 것같아서 적는다.
자바의 keyword 중에 하나인 volatile은 대체 정확히 어떨 때 쓰는 것일까?
애초에 volatile은 뭘까?
volatile은 휘발성 이란 의미를 가지고 있다. 잘 날아간다는 말이니까. 금방금방 그 값이 사라진다고 말 할수도 있고, 그 값이 의미없어진다고도 말 할수 있겠다.
volatile은 값을 읽고, 쓰는 것에 대한 원자성(Atomic)을 유지해주는 것 같다.

왜 이게 필요한가 하면 멀티스레드 환경에서 스레드 각각이 변수들의 값을 캐싱해서 사용한다는 것때문이다. 덕분에 값을 조회할 때마다 실제 값을 조회할 필요가 없이 사용할 수 있지만 만약 공유하는 값이 있고 그 값이 자주 변한다면 문제가 생길 수 있지 않을까?
그때 volatile을 사용하면 되지 않을까 싶다.

public class VolatileTest {
  private static volatile int count = 0;
//private static int count = 0;
  public static void main(String[] args) {
    new IwillGetIt().start();
    new IwillChangeIt().start();
  }  
  
  static class IwillGetIt extends Thread {
    @Override
    public void run() {
      int my_local = count;
      while (my_local < 5) {
        if (my_local != count){
          System.out.println("바꼈다!!! : " + count);
   my_local = count;
 }
      }
    }
  } 
  static class IwillChangeIt extends Thread {
    @Override
    public void run() {
      int my_local = count;
      while (my_local < 5 ) {
        System.out.println("값을 증가 시킴 : " + (++my_local));
        count = my_local;
        try {
          Thread.sleep(2000);
        } catch (InterruptedException e) {
   e.printStackTrace();
 }
      }
    }
  }
}
어떻게 될까? 위의 내용은 volatile을 넣은 것이다. count라는 값은 두개의 스레드가 공유를 한다. 서로 IwiilChangeIt은 바꾸는 아이고 IwillGetIt은 바꾸는 현장을 포착하는 아이다.
값을 증가 시킴 : 1
바꼈다!!! : 1
값을 증가 시킴 : 2
바꼈다!!! : 2
값을 증가 시킴 : 3
바꼈다!!! : 3
값을 증가 시킴 : 4
바꼈다!!! : 4
값을 증가 시킴 : 5
바꼈다!!! : 5
그렇다면 이 상태에서 저 위에 volatile이 없는 녀석의 주석을 풀고, volatile이 있는 녀석은 주석을 걸어보고 다시 실행하자.
값을 증가 시킴 : 1
바꼈다!!! : 1
값을 증가 시킴 : 2
값을 증가 시킴 : 3
값을 증가 시킴 : 4
값을 증가 시킴 : 5
그렇다면 volatile은 항상 쓰는 것이 스마트한 것일까?
난 잘 모르겠지만 그렇게는 쓰지 않는 것이 좋을 것 같다. 왜냐하면?
1. volatile은 변수에게 특권을 주는 것과 같다. 그 특권을 남발하면 안된다.
2. volatile을 모든 변수에게 주면 코드가 지저분하다.
3. 1번과 일맥상통한 것인데 volatile을 죄다 쓰면 누가 진짜 필요한 volatile인지 누가 알 수 있을까. 왜 이렇게 썼는지 고민하고 있지 않을까?
4. 성능의 이슈는 없을까? 하지만 이건 아직 내가 신경쓸 것은 아닌 듯 하다.

댓글 없음:

댓글 쓰기