스레드에서 동기화가 필요한 이유는 다음과 같습니다.
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
하나의 쓰레드가 공유데이터에 접근 하는 동안은
다른 쓰레드는 접근 할 수 없기에 안전하게 공유데이터에 데이터를 쓰는 작업이 가능하다.
데이터 동기화는 매우 중요하다.
예로 은행 인출잔고 역시 동기화가 되지 않는다면 사상초유의 사태가 발생할 수도 있다. ^^
감사합니다.
'앱 만들기 > 안드로이드 study' 카테고리의 다른 글
데몬쓰레드 만들기 (6) | 2022.06.06 |
---|---|
쓰레드 중지 시키기. (6) | 2022.06.03 |
익명클래스 는 언제 사용되나요? (6) | 2022.04.23 |
Java - 중첩 인터페이스가 필요한 이유 (6) | 2022.04.22 |
자바 예외처리가 필요한 이유 (4) | 2022.03.12 |
댓글