Java - 6. Thread: 공유객체, volatile

갓김치·2020년 9월 23일
1

고급자바

목록 보기
18/47

공유객체

  • 하나의 객체를 여러개의 Thread가 사용한다는 것을 의미
  1. 공통으로 사용할 데이터를 클래스로 정의한다.
  2. 공통으로 사용할 클래스의 인스턴스를 만든다.
  3. 이 인스턴스를 각각의 쓰레드에 넘겨 준다.
  4. 각각의 쓰레드는 이 인스턴스의 참조값을 저장한 변수를 이용하여 공통 데이터를 사용한다.

volatile

  • 선언된 변수를 컴파일러의 최적화 대상에서 제외 시킨다.
  • 즉, 값이 변경되는 즉시 변수에 적용시킨다.
  • 다중 쓰레드에서 하나의 변수가 완벽하게 한번에 작동되도록 보장하는 키워드 (일종의 동기화)
  • 추가설명
    • 하나의 Thread가 아닌 여러 Thread가 write하는 상황에서는 적합하지 않다
    • 여러 Thread가 write하는 상황이라면?
      • synchronized를 통해 변수 read & write의 원자성(atomic)을 보장해야함

예제: T14 원주율 계산

  • 원주율을 계산하는 쓰레드가 있고, 계산된 원주율을 출력하는 쓰레드가 있다.
  • 원주율을 계산한 후 이 값을 출력하는 프로그램을 작성하시오.
  • 이 때 원주율을 저장하는 객체가 필요하다.

1. 원주율을 관리하는 클래스 (공통으로 사용할 클래스)

class ShareDate {
  public double result; // 원주율이 저장될 변수.
  // 원주율 계산이 완료되었는지를 나타내는 변수
  volatile public boolean isOk = false;
}

2. 원주율을 계산하는 쓰레드

class CalcPIThread extends Thread {
  private ShareData sd;

  public CalcPIThread(ShareData sd) {
    this.sd = sd;
  }

  @Override
  public void run() {
    double sum = 0.0;

    for(int i=1 ; i<=1500000000; i+=2) {
      if (((i/2) % 2) == 0) { // 2로 나눈 몫이 짝수이면 +
        sum += (1.0/i);
      }else { // 2로 나눈 몫이 홀수 이면 -
        sum -= (1.0/i);
      }
    }
    sd.result = sum * 4; // 계산된 원주율을 공통객체의 멤버변수에 저장
    sd.isOk = true; // 계산이 완료되었음을 나타냄.
  }
}

3. 계산된 원주율을 출력하는 쓰레드

class PrintPIThread extends Thread {
  private ShareData sd;

  public PrintPIThread(ShareData sd) {
    this.sd = sd;
  }

  @Override
  public void run() {
    while(true) {
      // 원주율 계산이 완료될 때까지 기다린다.
      if(sd.isOk) {
        break;
      }
    }
    System.out.println();
    System.out.println("계산된 원주율 : " + sd.result);
    System.out.println("        PI : " + Math.PI);
  }
}

4. 프로그램이 실행되는 main()

// 공통으로 사용할 객체의 인스턴스 생성
ShareData sd = new ShareData();

// 처리할 쓰레드 객체 생성
CalcPIThread cpt = new CalcPIThread(sd);
PrintPIThread ppt = new PrintPIThread(sd);

cpt.start();
ppt.start();
profile
갈 길이 멀다

0개의 댓글