/*동기화(Synchronized):스레드가 사용 중인 객체를 다른 스레드가 변경할 수 없도록 스레드 작업이 끝날 때까지 객체에 잠금을 걸어 다른 스레드가 사용할 수 없도록 하는 것 스레드 작업이 끝날 때까지 객체에 잠금을 걸어 다른 스레드가 사용할 수 없도록 함 사용하려는 내용은 모두 동기화 안쪽으로 묶어줘야함 동기화의 종류: 무한루프(비효율적)/동기화 블록/동기화 메소드 ->동기화 블록을 메소드보단 대체로 자주 사용 */ package Day3; class Bank implements Runnable { private long depositeMoney = 10000; //long타입으로 depositeMoney는 10000으로 선언 public void run() { synchronized (this) { //동기화 (this : 이 클래스 안에서만) for (int i = 0; i < 10; i++) { //for문 notify(); //여러 스레드의 중첩 실행을 방지할 때 사용하는 메소드이다 try { //예외 처리 wait(); Thread.sleep(1000); //1초마다 출력되게 설정 } catch (InterruptedException e) { e.printStackTrace(); } if (getDepositeMoney() <= 0) //if문 만약 depositeMoney(10000)을 가져와서 0보다 작거나 같아지면 break; //나가기 withDraw(1000); //withdraw에 1000원씩 빠지도록 설정 } } } public void withDraw(long howMuch) { //long타입의 howMuch를 불러오는 withDraw를 만든다 Bank bk = new Bank(); //객체 생성 if (getDepositeMoney() > 0) { //if문 만약 가져오는depositeMoney(10000)이 0보다 크면 depositeMoney -= howMuch; //=> depositeMoney(10000) - howMuch(1000) = depositeMoney(9000) System.out.print(Thread.currentThread().getName()+ " , "); //현재 쓰레드의 이름을 가져오고(mother) ,까지 출력 System.out.printf("잔액 : %,d 원 %n",getDepositeMoney()); //1000원이 빠진 depositeMoney를 가져와서 출력한다 } else { System.out.print(Thread.currentThread().getName()+ " , "); //아니면 0이랑 같거나 0보다 작으면 System.out.println("잔액이 부족합니다."); //잔액이 부족합니다를 출력 } } public long getDepositeMoney() { //필드에 접근하기 위한 함수를 생성하고 return depositeMoney; //반환되는 돈을 반환한다 } } public class SynchronizedEx { public static void main(String[] args) { Bank bk = new Bank(); //객체생성 Thread mother = new Thread(bk, "mother"); //객체선언 및 생성(환경, 쓰레드의 이름 ) Thread son = new Thread(bk, "son"); //객체선언 및 생성(환경, 쓰레드의 이름) mother.start(); //mother객체 시작 son.start(); //son객체 시작 } }