내가 보려고 정리하는/JAVA

쓰레드로 은행의 입출금 처리하기! (동기화 처리 예제)

보동이용용 2022. 12. 28. 09:52
반응형

일단. 은행에 잔액과 출금 메서드를 넣어보자.

 

 

 

	private int balance;			// 잔액이 저장될 변수
	
	public int getBalance() {
		return balance;
	}

	public void setBalance(int balance) {
		this.balance = balance;
	}

	// 입금을 처리하는 메서드 
	public void deposit(int money) {
		balance += money;
	}
    
    
	// 출금을 처리하는 메서드 (반환값 : 출금 성공(true), 출금 실패(false))
	public ✓✓synchronized boolean withdraw(int money) {
		
		if(balance>=money) {	// 출금 가능 여부 검사

			for(int i=1; i<=100_000_000; i++) {  }      // 시간 지연용
			
			balance -= money;
			System.out.println("메서드 안에서 balance = " + balance);
			return true;
		}else {
			return false;
		}
	}

 

✓✓synchronized 표시해둔 곳에 가보면 동기화가 되어있다.

왜 이곳에 동기화를 해두었을까?

 

 

객체를 생성해서 실행해보자.

	public static void main(String[] args) {
		ThreadTest16 test = new ThreadTest16();
		test.setBalance(10000);		// 잔액을 10000원으로 설정
		
		// 익명 구현체로 쓰레드 구현
		Runnable runner = new Runnable() {
			
			@Override
			public void run() {
				boolean result = test.withdraw(6000);	// 6000원 출금하기
				System.out.println("쓰레드에서 출금 성공 여부 : " + result + 
									", balance : " + test.getBalance());
			}
		};
		//-----------------------------------------------
		
		Thread th1 = new Thread(runner);
		Thread th2 = new Thread(runner);
		
		th1.start();
		th2.start();

	}

 

 

여기서 공통으로 사용할 자료는 무엇인가?

 

 

바로, "출금 메서드"

 

그렇기 때문에 출금메서드에 동기화 처리를 했다.

 

-----  (동기화 전) 결  과  -----

메서드 안에서 balance = -2000
쓰레드에서 출금 성공 여부 : true, balance : 4000
쓰레드에서 출금 성공 여부 : true, balance : -2000

 

// 동기화 하지 않으면 잔금이 부족해서 걸려야하는 부분에서 걸리지 않고 같이 실행해버려서 마이너스가 되어버린다. 

 

 

 

 

-----  (동기화 후) 결  과  -----

메서드 안에서 balance = 4000
쓰레드에서 출금 성공 여부 : true, balance : 4000
쓰레드에서 출금 성공 여부 : false, balance : 4000

 

 

 

// 지금은 출금만 했기에 출금메서드에만 동기화 처리를 했다.

 

반응형