4-4(1). Thread 동기화

zhyun·2020년 9월 23일
0

HighJava

목록 보기
31/67
post-custom-banner

Thread 동기화

1. 동기화란?

  • 동기화 (Synchronization)
    : 공유자원(객체)를 상대순서대로 작업이 이루어지도록 처리하는 방법을 의미한다.

2. 동기화가 필요한 이유

  • 프로세스 내 자원(객체)를 여러개의 스레드가 공유하여 작업을 진행하다 보면 예기치 못한 결과를 초래
  • 문제가 발생할 여지가 있을 법한 임계영역동기화 처리를 해줌으로써 문제 방지
  • 과도한 동기화는 전체적으로 프로그램의 성능을 저하시키기 때문에 필요한 영역만 선별적으로 사용

3. Thread에서 데이터를 "공통으로" 사용하는 방법

  • 공통으로 사용할 데이터클래스로 정의한다.
  • 공통으로 사용할 클래스의 인스턴스를 만든다.
  • 인스턴스를 각각의 쓰레드에 넘겨준다.
  • 각각의 쓰레드는 이 인스턴스의 참조값을 저장한 변수를 이용하여 공통 데이터를 사용한다.

T14_ThreadShareDataTest

  • 공통으로 사용할 클래스 ShareData의 객체 sd로 생성
  • 생성한 객체 sd를 각각 쓰레드 객체 생성할때 넘겨줌
  • 아래 예시
public class T14_ThreadShareDataTest {
	public static void main(String[] args) {
		//공통으로 사용할 객체의 인스턴스 생성
		ShareData sd = new ShareData();
		
		//처리할 쓰레드 객체 생성
		CalcPIThread cpt = new CalcPIThread(sd);
		PrintPIThread ppt = new PrintPIThread(sd);
		
		cpt.start();
		ppt.start();
	}
}

volatile

  • 선언된 변수를 컴파일러의 최적화 대상에서 제외시킨다.
  • 즉, 값이 변경되는 즉시 변수에 적용시킨다.
  • 다중 쓰레드(Multi Thread)에서 하나의 변수가 완벽히 한번에 작동되도록
    보장하는 키워드 (일종의 동기화)

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

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

원주율을 계산하는 쓰레드

class CalcPIThread extends Thread{
	private ShareData sd;
	
	public CalcPIThread(ShareData sd) {
		this.sd = sd;
	}
	
	@Override
	public void run() {
/**
 *  원주율 = (1/1 - 1/3 + 1/5 - 1/7 + 1/9.....) *4; -> *4를 해줘야 파이값
 *           1  +  3  +  5  -  7  +  9 => 분모
 *           0     1     2     3     4 => 2로 나눈 몫	
 */
		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; //계산이 완료되었음을 나타냄
	}//run
}//class

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

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);
	}// run
}// class
profile
HI :)
post-custom-banner

0개의 댓글