멀티스레드를 사용할 때는 이런 공유 자원에 대한 접근을 적절하게 동기화(synchronization)해서 동시성 문제가 발생하지 않게 방지하는 것이 중요하다
동시성 문제는 valatile 키워드를 도입해도 해결되지 않는다.
임계 영역(critical section)
지역 변수는 스레드의 개별 저장 공간인 스택 영역에 생성된다. 따라서 지역 변수는 절대로! 다른 스레드와 공유되지 않는다!
필드에 final 이 붙으면 어떤 스레드도 값을 변경할 수 없다. 따라서 멀티스레드 상황에 문제 없는 안전한 공유 자원이 된다
@Override
public synchronized boolean withdraw(int amount) {}
@Override
public boolean withdraw(int amount) {
log("거래 시작: " + getClass().getSimpleName());
synchronized (this) {
log("[검증 시작] 출금액: " + amount + ", 잔액: " + balance);
if (balance < amount) {
log("[검증 실패] 출금액: " + amount + ", 잔액: " + balance);
return false;
}
// 잔고가 출금액 보다 많으면, 진행
log("[검증 완료] 출금액: " + amount + ", 잔액: " + balance);
sleep(1000); // 출금에 걸리는 시간으로 가정
balance = balance - amount;
log("[출금 완료] 출금액: " + amount + ", 잔액: " + balance);
}
log("거래 종료");
return true;
}