공유객체
- 하나의 객체를 여러개의 Thread가 사용한다는 것을 의미
- 공통으로 사용할 데이터를 클래스로 정의한다.
- 공통으로 사용할 클래스의 인스턴스를 만든다.
- 이 인스턴스를 각각의 쓰레드에 넘겨 준다.
- 각각의 쓰레드는 이 인스턴스의 참조값을 저장한 변수를 이용하여 공통 데이터를 사용한다.
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) {
sum += (1.0/i);
}else {
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();