package ch02;
작업자들이 자원(데이터)를 공유하는 상황일 때 처리하는 방법
class BankAccount{
private int money = 100_000;
//getter
public int getMoney() {
return this.money;
}
//setter
public void setMoney(int money) {
this.money = money;
}
//입금 기능
public void saveMoney(int money) {
synchronized (this) {
//10만원 상태
int currentMoney = getMoney();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
setMoney(currentMoney + money);
System.out.println("입금 후 계좌 잔액 : " + getMoney());
}
}
//출금기능
public synchronized void widthdrawMoney(int money) {
//10만원 상태
int currentMoney = getMoney();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
//방어적코드
if(currentMoney >= money) {
setMoney(currentMoney- money);
System.out.println("출금 후 계좌 잔액 : " +getMoney());
}else {
System.out.println("잘못된 입력입니다.");
}
}
}//class
//아버지
class Father extends Thread {
BankAccount account;
public Father(BankAccount account) {
this.account = account;
}//(BankAccount account) 존재할수 있도록 생성자에서 미리 만들어준다.
@Override
public void run() {
//입금하기
account.saveMoney(10_000);
}//입금하는 동작이 오래 걸려서 런을 넣는다
}
//어머니
class Mother extends Thread {
BankAccount account;
public Mother(BankAccount account) {
this.account = account;
}
@Override
public void run() {
//출금하기
account.widthdrawMoney(5_000);
}
}
public class SharedResource {
public static void main(String[] args) {
현재 10 만원이 저금되어 있는 상태로 객체 생성
BankAccount account = new BankAccount();
Father father = new Father(account); //account로 공유
Mother mother = new Mother(account);//shared resource
//아버지가 입금하는 동작
father.start(); //쓰레드 호출
//어머니가 출금하는 동작
mother.start();
정상처리 금액 : 10만원 + 1만원 - 5천원 = 10만5천원
결과값: 출금후95000 / 입금후110000
의도치 않은 결과
임계 영역이 발생될 때(작업자간에 자원을 공유하는 상태)
다른 작업자가 사용하지 못하도록 lock을 걸어준다.-하는 방법 : 동기화 처리를 한다.(synchronization)
순차적으로 작업할수있도록
1.synchronized 메서드를 사용하는 방법 - public synchronized
1번은 메서드 전체가 블록
2.synchronized 블럭을 사용하는 방법 -입금안에 synchronized 블럭을 생성해서 사용
2번은 디테일하게 한구역만 블록처리해서 사용하기 용이
}
}