앱 만들기/안드로이드

쓰레드 동기화

나도 처음이야 2022. 5. 11.

스레드에서 동기화가 필요한 이유는 다음과 같습니다.

A, B 스레드가 공통 데이터에 접근을 합니다.

A, B 각각 공통 데이터에 값을 설정합니다.

우리가 기대한 결과는 A 가 설정된 후 A의 값이 나오고

B는 B의 설정된 값이 나오길 원합니다.

 

그런데, 결과는 하나의 스레드가 값을 세팅하는 중 다른 스레드가 덮어쓰기를 하게 됩니다.

즉, 마지막에 실행된 스레드가 값을 덮어쓰기 하게 되는 것입니다.

바로 스레드의 동기화가 필요한 시점입니다.

 

공용데이터 shareData

public class ShareClass {
	
	int shareData;

	 void setData(int num) {
		shareData = num;
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(Thread.currentThread().getName() + ": shared data = " + shareData);
	}
}

두개의 쓰레드가 하나씩 공용데이터 인 shareData 에 접근한다.

public class ThreadTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		ShareClass sc = new ShareClass();
		
			Thread A = new Thread() {
				
				@Override
				public void run() {
					// TODO Auto-generated method stub
					sc.setData(100);					
				}
			};
			
			Thread B = new Thread() {

				@Override
				public void run() {
					// TODO Auto-generated method stub
					sc.setData(200);				
				}				
				
			};

			B.start();
			B.setName("B");
			A.start();
			A.setName("A");
			
	}	

}

하지만, 결과는 우리가 생각하듯 쓰레드는 하나씩 접근하지 않는다.

원치 않는 결과가 나왔다.

 

A: shared data = 100
B: shared data = 100

 

공용데이터에 접근할때는 이런 이유때문에, 쓰레드 동기화가 필요하다.

쓰레드 동기화 = 하나의 쓰레드가 접근할때 다른 쓰레드는 접근 할 수 없게 만드는 것.

 

만드는 방법은 간단하다.

공용데이터에 접근하는 함수에 synchronized 키워드를 붙여준다.

public class ShareClass {
	
	int shareData;

	 synchronized void setData(int num) {
		shareData = num;
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(Thread.currentThread().getName() + ": shared data = " + shareData);
	}
}

그럼 결과는, 정상적으로 나온다

B: shared data = 200
A: shared data = 100

 

하나의 쓰레드가 공유데이터에 접근 하는 동안은

다른 쓰레드는 접근 할 수 없기에 안전하게 공유데이터에 데이터를 쓰는 작업이 가능하다.

데이터 동기화는 매우 중요하다.

예로 은행 인출잔고 역시 동기화가 되지 않는다면 사상초유의 사태가 발생할 수도 있다. ^^

감사합니다.

반응형

댓글