국비 과정/Java
국비 - 0722 (Synchronization(동기화))
by 코딩호야
2022. 7. 22.
Synchronization(동기화)
지금까지의 스레드는 각기 독립적으로 작동했습니다.
이런경우에 여러개의 스레드가 동시에 공유된 하나의 값에 접근 한다면
문제가 생길수 있습니다.
예를들어 ATM(은행 자동화기기)을 사용할 경우에 ATM 을
사용할수 있는 카드를 여러장 발급할수 있습니다.
만약 3사람이 각자 같은 계좌를 이용할수 있는 ATM 카드를
가지고있다면 그 세사람이 동시에 서로 다른 ATM을 이용해
입출금을 시도할수 있습니다. 이럴경우 발생하는 문제를 해결하는 방법을 제공합니다.
여러개의 은행카드는 하나의 계좌에 입출금을 할수 있습니다.
이런경우 동시에 공유된 값에 접근할수 있는 스레드는 하나로
제한할 필요가 있습니다. 이런작업을 처리하기 위해 자바에서는
동기화 기법이 존재합니다 . 즉 Synchronization(동기화)는
한시점에 하나의 스레드만 공유된 값을 변경 시킬수 있습니다.
이때 스레드에 의해 공유된 값을 임계영역(Critical Section) 이라하고
임계영역 지정은 synchronized 키워드를 이용해 처리합니다.
하나의 스레드가 임계영역으로 지정된 변수나 메서드를 호출할때
다른 스레드가 그 값에 접근할수 없도록 lock 을 걸고 사용이
끝나면 락을 해제 합니다.
동기화 처리방법
1. 공유데이터에 접근하는 메서드를 synchronized 키워드로
처리합니다.
synchronized 메서드(){
....; //공유데이터 접근
}
2. 공유데이터에 접근되는 영역을 synchronized 키워드로 블록화
처리합니다. 이때 공유 자원을 가지고 있는 클래스 객체를 사용합니다.
synchronized(클래스객체){
...; //처리할 블럭
}
class ATM {
private int total;
public ATM() {
}
public ATM(int total) {
this.total = total;
}
synchronized void desposit(int amount, String name) {
total += amount;
System.out.println(name + " 님 입금 금액 :" + amount + " 원 ");
}
synchronized void withfraw(int amount, String name) {
if ((total - amount) > 0) { // 출금가능하면
total -= amount;
System.out.println(name + " 님 출출금액 :" + amount + " 원 ");
} else {
System.out.println(name + " 님 잔액이 부족해 출금불가합니다.");
}
}
public void getTotal() {
System.out.println("\n 현재 계좌의 금액 : " + total + "원\n");
System.out.println("===========================");
}
}
class ATM_USER extends Thread // ATM 사용자
{
boolean flag = false;
ATM obj; // 멤버로 obj를 가지고있음
public ATM_USER(ATM obj, String name) {
super(name);
this.obj = obj;
}
public void run() {
for (int i = 0; i < 5; i++) {
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (flag) {
obj.desposit((int) (Math.random() * 10000), getName());
obj.getTotal();
} else {
obj.withfraw((int) (Math.random() * 10000), getName());
obj.getTotal();
}
flag = !flag;
}
}
}
class MyATM {
public static void main(String[] args) {
ATM atm = new ATM(10000); // 계좌에 만원이 들어있음
ATM_USER user1 = new ATM_USER(atm, "유현진");
ATM_USER user2 = new ATM_USER(atm, "손흥민");
ATM_USER user3 = new ATM_USER(atm, "우상혁");
user1.start();
user2.start();
user3.start();
}
}
첫번째 방법 synchronized 키워드로 이용해서 처리한 예제이다.
은행 ATM 예제이고 전체적인 코드 흐름을 파악해볼수 있는 예제이다.