24-2: JAVA synchronized

jk·2024년 2월 1일
0

kdt 풀스택

목록 보기
46/127



1.임계 영역이란?

  • Sometimes different threads can use mutual section at the same time.
  • In the mutual section, some unexpected or weird conflicts may happen.
  • The mutual section is critical section.



2.synchronized 키워드에 대하여 설명하시오.

  • It doesnt let the method be used by multiple threads at the same time.



3.쓰레드를 메모리 그림으로 설명하시오



4. 아래와 같이 출력되도록 소스코드를 수정하시오.

Thread-0:1번
Thread-0:1번
​
Thread-2:3번
Thread-2:3번
​
Thread-1:2번
Thread-1:2번
​
Thread-4:5번
Thread-4:5번
​
Thread-3:4번
Thread-3:4번
class StringPrint{
	synchronized void display(String s) {
//		
		for(int i = 1; i <= 2; i++) {
			System.out.print(Thread.currentThread().getName() + ":");
			System.out.print(s);
			System.out.println();
		}
		System.out.println();
//		
	}
}
//
class PrintThread extends Thread{
	private StringPrint sp;
	private String str;
//	
	public PrintThread(String s , StringPrint sp) {
		this.str = s;
		this.sp = sp;
	}
//	
	@Override
	public void run() {
		sp.display(str);
	}	
}
//
//code
//
class PrintThreadMain {
    public static void main(String[] args) {
        StringPrint stringPrint = new StringPrint();
//        
        Thread thread1 = new PrintThread("1번", stringPrint);
        Thread thread2 = new PrintThread("2번", stringPrint);
        Thread thread3 = new PrintThread("3번", stringPrint);
        Thread thread4 = new PrintThread("4번", stringPrint);
        Thread thread5 = new PrintThread("5번", stringPrint);
 //       
        thread1.start();
        thread2.start();
        thread3.start();
        thread4.start();
        thread5.start();
    }
}
/*print
Thread-1:2번
Thread-1:2번
​
Thread-4:5번
Thread-4:5번
​
Thread-3:4번
Thread-3:4번
​
Thread-2:3번
Thread-2:3번
​
Thread-0:1번
Thread-0:1번
*/



5. 아래의 소스코드가 -100 이 나오는 이유를 설명하고, 수정하시오.

class Accout{
	private int balance = 1000;
//	
	public int getBalance() {
		return balance;
	}
//	
	public void withdraw(int money) throws Exception {
		if(balance >= money) {  //300
			Thread.sleep(1000); // 다른 쓰레드한테 CPU 양보
			balance = balance - money;
		}
	}	
}
//
class AccountThread implements Runnable{
	Accout accout = new Accout();
//	
	@Override
	public void run() {
//		
		while(accout.getBalance() > 0) {  //1000
			// 100, 200, 300중의 한 값을 임으로 선택해서 출금(withdraw)
			int money = (int)(Math.random() * 3 + 1) * 100; //300
//			
			try {
				accout.withdraw(money);
			} catch (Exception e) {
					e.printStackTrace();
			}
//			
			System.out.println("balance:"+accout.getBalance()); //-100 이 찍힘
		}
	}	
}
//
//main 메소드
//=======================
Runnable r = new AccountThread();
new Thread(r).start(); 
//	
new Thread(r).start();
//
//code
//
	//public void withdraw(int money) throws Exception {
	public synchronized void withdraw(int money) throws Exception {
  • Because of critical section.
  • One withdrew money when the other is sleeping.
  • Both calculated for only itself, so they withdrew money more than the balance.
  • synchronized blocks the critical section, so it doesnt let two threads sleep and withdraw the money together.



6. 아래를 프로그래밍 하시오.

HashMap<String, Integer> 컬렉션을 생성하고
“에스프레소”는 2000, “아메리카노”는 2500, “카푸치노”는 3000, “카페라테”는 3500을 저장하라.
그리고 다음과 같이 음료수 이름을 입력받으면 HashMap에서 검색하여 가격을 출력하라.

//
//code
//
import java.util.*;
final class Const {
    final static String ESPRESSO = "에스프레소";
    final static String AMERICANO = "아메리카노";
    final static String CAPPUCCINO = "카푸치노";
    final static String LATTE = "카페라테";
    final static int ESPRESSO_PRICE = 2000;
    final static int AMERICANO_PRICE = 2500;
    final static int CAPPUCCINO_PRICE = 3000;
    final static int LATTE_PRICE = 3500;
    final static String STOP = "그만";
    final static Map<String, Integer> MAP = new HashMap<String, Integer>() {
        {
            put(ESPRESSO, ESPRESSO_PRICE);
            put(AMERICANO, AMERICANO_PRICE);
            put(CAPPUCCINO, CAPPUCCINO_PRICE);
            put(LATTE, LATTE_PRICE);
        }
    };
}
final class Mut {
    //static Scanner scanner = new Scanner(System.in);
    static Scanner scanner = new Scanner(System.in, "Cp949");
    static Thread cafe = new CafeThread();
    static String input;
}
final class Print {
    private static StringBuilder print = new StringBuilder();
    final private static void reset() {
        print.setLength(0);
    }
    final private static void printAndReset() {
        System.out.print(print);
        reset();
    }
    final static <T> void print(T t) {
        print.append(t);
        printAndReset();
    }
    final private static void printlnAndReset() {
        System.out.println(print);
        reset();
    }
    final static <T> void println(T t) {
        print.append(t);
        printlnAndReset();
    }
}
final class Fn {
    final static void runMain() {
        while(true) {
            try {
                Mut.cafe.start();
                break;
            } catch(Exception e) {
                e.printStackTrace();
            };
        };
    }
    final static void inputDrink() {
        while(true) {
            Print.print("음료 이름을 입력해주세요: ");
            Mut.input = Mut.scanner.next();
            if(Mut.input.equals(Const.STOP)) {
                Mut.scanner.close();
                break;
            } else if(Const.MAP.containsKey(Mut.input)) {
                Print.print(Const.MAP.get(Mut.input));
                Print.println(" 원 입니다.");
            } else {
                Print.println("우리 카페는 그런 음료는 팔지 않습니다. 나가시려면 \"그만\"을 입력해주세요.");
            };
        };
    }
}
final class CafeThread extends Thread {
    CafeThread() {
        super();
    }
    @Override
    final public void run() {
        while(true) {
            try {
                Fn.inputDrink();
                break;
            } catch(Exception e) {
                e.printStackTrace();
                //Mut.scanner = new Scanner(System.in);
                Mut.scanner = new Scanner(System.in, "Cp949");
            };
        };
    }
}
final class CafeMain {
    final public static void main(String[] args) {
        Fn.runMain();
    }
}
/*print
음료 이름을 입력해주세요: 에스프레소
2000 원 입니다.
음료 이름을 입력해주세요: 카푸치노
3000 원 입니다.
음료 이름을 입력해주세요: 카페라테
3500 원 입니다.
음료 이름을 입력해주세요: 아메리카노
2500 원 입니다.
음료 이름을 입력해주세요: 라면
우리 카페는 그런 음료는 팔지 않습니다. 나가시려면 "그만"을 입력해주세요.
음료 이름을 입력해주세요: 그만
*/
profile
Brave but clumsy

0개의 댓글