Thread 예제4: 동기화를 이용한 입출금 프로그램

·2022년 11월 5일
0

JAVA객체지향_Thread

목록 보기
7/7

코드가 길어서 이클립스에서 작성한 뒤 복사해왔다.

문제:

스레드 동기화를 이용해서 입출금 프로그램을 작성하시오.(선택지: 1.입금 2.출금 3.종료)

필요한 것:

  • 공유객체(MyBank)=> 계좌, 잔액(private변수), private변수를 사용할 set,get메소드, 입금 메소드, 출금 메소드
  • 입금 스레드
  • 출금 스레드
  • 선택지 : while문, switch문

1. 큰 틀 작성하기

import java.util.Scanner;

//예외 만들기
class BankException extends RuntimeException{
	public BankException(String msg) {
		super(msg);
	}
}
//공유객체
class MyBank{  //필요한 변수(private): 계좌번호(String), 잔액(long) / 필요한 메소드: 입금, 출금, 값 세팅(set), 입력한 값 리턴(get)
	private String num;
	private long money;
	//생성자
	public MyBank(String num,long money) {
		this.num=num;
		this.money=money;
	}
	//입금 메소드, 인자: 입금할 금액
	public void deposit(long m) {
		this.money+=m;	//money는 private 변수니까 this.로 인자 만들어줌. +=로 금액 합산
	}
	//출금 메소드
	public void withdraw(long m) {
		//출금할 금액이 잔액보다 크면 throw로 예외 던져줌
		if(m>money) {
			throw new BankException("잔액부족");
		}
		this.money-=m;
	}
	public void setNum(String num) {
		this.num = num;
	}
	public void setMoney(long money) {
		this.money = money;
	}
	//getNum: private변수 계좌 불러오기
	public String getNum() {
		return num;
	}
	//getMoney: private변수 잔액 불러오기
	public long getMoney() {
		return money;
	}
}
//입금스레드
class InputThread extends Thread{
	@Override
	public void run() {
		//공유객체를 인자로 갖는 동기화메소드
		synchronized(){
		}
	}
}
//출금 스레드
class OutputThread extends Thread{
	@Override
	public void run() {
		synchronized(){			
		}
	}
}

public class Test03_Quiz_입출금프로그램 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		System.out.println("계좌를 입력해주세요");
		String num = sc.next();
		MyBank b = new MyBank(num,50000);
		while(true) {
			System.out.println("<<실행할 메뉴 고르시오.>>");
			System.out.println("1.입금 2.출금 3.종료");
			int s = sc.nextInt();
			switch(s){
				case 1: 
					System.out.println("입금할 금액을 입력하세요.");
					long m = sc.nextLong();
					new InputThread(b,m).start(); break;
				case 2: 
					System.out.println("출금할 금액을 입력하세요.");
					long m1 = sc.nextLong();
					new OutputThread(b,m1).start(); break;
				case 3: System.out.println(b.getNum()+"계좌의 잔액은 "+b.getMoney()+"원 입니다.");
					System.exit(0);
			}
		}
	}
}

2. 구현부 작성

import java.util.Scanner;

//예외 만들기
class BankException extends RuntimeException{
	public BankException(String msg) {
		super(msg);
	}
}
//공유객체
class MyBank{  //필요한 변수(private): 계좌번호(String), 잔액(long) / 필요한 메소드: 입금, 출금, 값 세팅(set), 입력한 값 리턴(get)
	private String num;
	private long money;
	//생성자
	public MyBank(String num,long money) {
		this.num=num;
		this.money=money;
	}
	//입금 메소드, 인자: 입금할 금액
	public void deposit(long m) {
		this.money+=m;	//money는 private 변수니까 this.로 인자 만들어줌. +=로 금액 합산
	}
	//출금 메소드
	public void withdraw(long m) {
		//출금할 금액이 잔액보다 크면 throw로 예외 던져줌
		if(m>money) {
			throw new BankException("잔액부족");
		}
		this.money-=m;
	}
	public void setNum(String num) {
		this.num = num;
	}
	public void setMoney(long money) {
		this.money = money;
	}
	//getNum: private변수 계좌 불러오기
	public String getNum() {
		return num;
	}
	//getMoney: private변수 잔액 불러오기
	public long getMoney() {
		return money;
	}
}
//입금스레드
class InputThread extends Thread{
	long m; 
	MyBank b;
	public InputThread(MyBank b,long m) {
		this.m=m;
		this.b=b;
	}
	@Override
	public void run() {
		//공유객체를 인자로 갖는 동기화메소드
		synchronized(b){
			System.out.println("입금중>>>>>>>>>>>>");
			for(int i=1;i<=100000;i++); // 시간 지연 for문
			b.deposit(m);
			System.out.println("입금이 완료되었습니다. 현재 계좌의 잔액은 "+b.getMoney()+"원 입니다.");
		}
	}
}
//출금 스레드
class OutputThread extends Thread{
	long m;
	MyBank b;
	public OutputThread(MyBank b,long m) {
		this.b=b;
		this.m=m;
	}
	@Override
	public void run() {
		synchronized(b){
			System.out.println("출금중>>>>>>>>>>>>>>");
			for(int i=0;i<=100000;i++);
			try {
				b.withdraw(m);
				System.out.println("출금이 완료되었습니다. 현재 계좌의 잔액은 "+b.getMoney()+"원 입니다.");
			}catch(BankException be) {
				System.out.println(be.getMessage());
			}
			
		}
	}
	
}

public class Test03_Quiz_입출금프로그램 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		System.out.println("계좌를 입력해주세요");
		String num = sc.next();
		MyBank b = new MyBank(num,50000);
		while(true) {
			System.out.println("<<실행할 메뉴 고르시오.>>");
			System.out.println("1.입금 2.출금 3.종료");
			int s = sc.nextInt();
			switch(s){
				case 1: 
					System.out.println("입금할 금액을 입력하세요.");
					long m = sc.nextLong();
					new InputThread(b,m).start(); break;
				case 2: 
					System.out.println("출금할 금액을 입력하세요.");
					long m1 = sc.nextLong();
					new OutputThread(b,m1).start(); break;
				case 3: System.out.println(b.getNum()+"계좌의 잔액은 "+b.getMoney()+"원 입니다.");
					System.exit(0);
			}
		}
	}
}
//고찰 : 입력금액을 메소드에 줘버리면 프로그램이 이상하게 돌아간다.. 왜인지 한참 고민했지만 모르겠다. 중복출력이 된다 큼..ㅎ
profile
웹개발입문자

0개의 댓글