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 원 입니다. 음료 이름을 입력해주세요: 라면 우리 카페는 그런 음료는 팔지 않습니다. 나가시려면 "그만"을 입력해주세요. 음료 이름을 입력해주세요: 그만 */