back/Java

KH 17일차(Thread로 ATM 예제[Synchronization])

devel0per 2022. 7. 24. 13:05

저번 시간에 학습한 Thread를 활용하여 ATM 기기 예제를 학습했다.

물론 Thread만을 학습하기 위해서 예제를 활용한 것은 아니구, Synchronization(동기화)를 학습하기 위해서 ATM기기 예제를 학습했다.

여러개의 은행카드(스레드)는 하나의 계좌(공용변수)에 입출금 할 수 있습니다. 동기화 처리를 하지 않는다면 스레드가 무분별하게 사용되어 원하는 값을 정확하게 추출하지 못하므로, 동기화 처리를 해서 한 시점에서 한 하나의 스레드만 공유된 값을 변경시킬 수 있도록 처리를 해야합니다.

 

 

class ATM_2{
	
	int total;
	
	public ATM_2(int total) {
		
		this.total = total;
	}
	
	synchronized void deposit(int amount, String name) {
		
		total += amount;
		System.out.println(name + " 님이 입금하신 금액은" + amount + " 입니다.");
	}
	
	synchronized void withdraw(int amount, String name) {
		
		if(total - amount > 0) {
			total -= amount;
			System.out.println(name + " 님이 출금하신 금액은" + amount + " 입니다.");
		}else {
			System.out.println("계좌에 돈이 부족하여 출금하실 수 없습니다.");
		}
	}
	
	void getTotal() {
		System.out.println("현재 계좌의 총 금액은 " + total);
	}
}


class ATM_USER_2 extends Thread{
	
	boolean flag = false;
	
	ATM_2 atm;
	
	public ATM_USER_2(ATM_2 atm, String name) {	
		super(name);
		this.atm = atm;
	}
	
	@Override
	public void run() {
		for(int i = 0;i < 5; i++) {
			try {
				sleep(1000);
			}catch(InterruptedException e) {
				e.printStackTrace();
			}
			
			if(flag) {
				atm.deposit((int)(Math.random() * 10000), getName());
				atm.getTotal();
			}else {
				atm.withdraw((int)(Math.random() * 10000), getName());
				atm.getTotal();
			}
			
			flag =! flag;
		}
	}
}
	
public class MyATM_2{
	public static void main(String[] args) {
		
		
		ATM_2 atm = new ATM_2(10000);
		
		ATM_USER_2 obj = new ATM_USER_2(atm, "전민우");
		
		obj.start();
	}
}

 

메서드를 선언하기 전에 synchronized를 간단하게 붙혀 사용해서 동기화 처리를 해줄 수 있다. 

 

 

import java.util.Date;

public class Date_1 {
	public static void main(String[] args) {
		
		Date date = new Date();
		
		int h = date.getHours();
		int m = date.getMinutes();
		int s = date.getSeconds();
		
		System.out.println(" 현재 시간은 : " + h + " 시 " + m + " 분 " + s);
		
		if(h>12) {
			System.out.println(" 현재 시간은 오후 : " +(h - 12) + " 시 " + m + " 분 " + s + " 초 ");
		}else {
			System.out.println(" 현재 시간은 오전 : " +h + " 시 " + m + " 분 " + s + " 초 ");
		}
	}
}

그 밖에도 java.util.Date를 import해서 date 객체 속 getHours(), getMinutes(), getSeconds() 메서드로 현재 시간의 시, 분, 초를 출력할 수 있다.

 

class Queen{
	int number;
	
	public Queen(int num) {
		
		number = num;
	}
}

// ==는 주소 비교다.
// equals 내용 비교다.


public class Equals_1 {
	public static void main(String[] args) {
		
		Queen obj_1 = new Queen(27);
		Queen obj_2 = new Queen(27);
		
		if(obj_1.equals(obj_2)) {
			System.out.println("obj_1 과 obj_2는 같다");
		}else {
			System.out.println("obj_1과 obj_2는 다다다르르다다다");
			
			System.out.println("obj_1 : " + obj_1.getClass().hashCode());
			System.out.println("obj_2 : " + obj_2.getClass().hashCode() + "\n");
		}
		
		if(obj_1 == obj_2) {
			System.out.println("obj_1 과 obj_2는 같다");
		}else {
			
			System.out.println("obj_1과 obj_2는 다다다르르다다다");
			System.out.println("obj_1 : " + obj_1.hashCode());
			System.out.println("obj_2 : " + obj_2.hashCode()+ "\n");
		}
		
		obj_2 = obj_1;
		
		if(obj_1.equals(obj_2)) {
			System.out.println("obj_1 과 obj_2는 같다");
		}else {
			System.out.println("obj_1과 obj_2는 다다다르르다다다");
			
			System.out.println("obj_1 : " + obj_1.hashCode());
			System.out.println("obj_2 : " + obj_2.hashCode()+ "\n");
		}
		
		if(obj_1 == obj_2) {
			System.out.println("obj_1 과 obj_2는 같다");
		}else {
			
			System.out.println("obj_1과 obj_2는 다다다르르다다다");
			System.out.println("obj_1 : " + obj_1.hashCode());
			System.out.println("obj_2 : " + obj_2.hashCode());
		}

	}

}

기본적으로 Java에선 ==와 equals는 양쪽값의 비교를 통해 출력된 결과값을 boolean형태로 출력한다는 공통점이 있다.

하지만 equals()는 메서드이고, ==은 비교 연산자이기 때문에 분명한 차이점이 존재한다. 

 

1. equals()는 대상 자체를 비교하지만, == 비교 연산자는 대상의 주소값을 비교한다는 차이점이 있다.

 

public class Practice_1 {
	public static void main(String[] args) {
		
		
		String a = "aa";
		String b = a;
		String c = new String("aa");
		
		System.out.println(a == b); // true 같은 주소값을 가지고 있기 때문에.
		System.out.println(a.equals(b)); // true 같은 주소값을 가지고 있고, 변수 속에 저장되어 있는 값도 똑같기 때문에.
		System.out.println(a.equals(c)); // true 다른 주소값을 가지고 있더라도, 변수 속에 저장되어 있는 값이 같기 때문에.
		System.out.println(a == c); // false 다른 주소값을 가지고 있기 때문에.

	}
}

코드를 보면 바로 이해가 될 것이다 !!