본문 바로가기

카테고리 없음

#21 라면 끓이기

냠냠,,

package com.sparta;

//TIP To <b>Run</b> code, press <shortcut actionId="Run"/> or
// click the <icon src="AllIcons.Actions.Execute"/> icon in the gutter.
public class RamenProgram {
    public static void main(String[] args) {
         try{
             RamenCook ramenCook=new RamenCook(Integer.parseInt("15"));
             //문자열 15를 int로 형변환 후 RamenCook 생성자에 매개변수로 넘겨서 ramenCook 객체를 생성

             new Thread(ramenCook, "A").start();
             new Thread(ramenCook, "B").start();
             new Thread(ramenCook, "C").start();
             new Thread(ramenCook, "D").start();
             //A, B, C, D라는 이름으로 각각의 ramenCook을 매개변수로 쓰레드 생성 후 실행
         }catch (Exception e){
             e.printStackTrace();
         }
        }
    }

    class RamenCook implements Runnable{
    private int ramenCount;
    private String[] burners={"_","_","_","_"};

    public RamenCook(int count){
        ramenCount=count;
    }

    @Override
        public void run(){
        while(ramenCount>0){  //라면 갯수 0보다 클 때 동안 반복함

            //임계영역 지정, 여러 스레드가 동시에 실행하는걸 막기 위해 lock을 걸어 독점
            synchronized (this){
                ramenCount--;
                System.out.println(
                        Thread.currentThread().getName()+" : " +ramenCount+ " 개 남음");
                //라면 갯수를 -1하고 라면 개수와 실행중인 스레드의 이름을 출력

            }

            for(int i=0; i<burners.length; i++){
                if(!burners[i].equals("_")) continue;
                //버너에 A, B, C,..같은게 채워져있으면 continue한다

                synchronized (this){
                    //if (burners[i].equals("_")) {
                    burners[i]=Thread.currentThread().getName();
                    System.out.println(
                            "                        " +Thread.currentThread().getName()+
                                    ": [" + (i+1)+"]번 버너 ON"
                    );     //버너가 "_" 이면 그 자리에 A,B,C,.. 같은걸 채우고 몇 번째 버너인지 출력
                    showBurners();
                    //}
                }

                try{
                    Thread.sleep(2000);  //현재 스레드를 2초간 재운다
                }catch(Exception e){
                    e.printStackTrace();
                }

                //임계영역 지정, 여러 스레드가 동시에 실행하는걸 막기 위해 lock을 걸어 독점
                synchronized (this){
                    burners[i]="_";
                    System.out.println(
                            "                                             "+
                                    Thread.currentThread().getName()+
                                    ": ["+(i+1) + "]번 버너 OFF"
                    ); //해당 자리를 다시 "_"로 만들고 해당 인덱스의 버너가 OFF되었다고 출력
                    showBurners();
                }
                break; //해당 스레드가 빈 버너를 찾아서 채우면 버너를 끄는 행동을 1회 수행하고 for문을 종료하고 다시 반복
            }
            try{
                Thread.sleep(Math.round(1000*Math.random())); //무작위 시간동안 기다리게 해서 다른 스레드가 고르게 버너를 사용하게 함
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    private void showBurners(){  //버너의 개수만큼 반복문을 돌며 stringToPrint 공백안에 버너의 내용을 하나씩 넣고 출력
        String stringToPrint
                = "                                                                          ";
        for(int i=0; i<burners.length; i++){
            stringToPrint+=(" "+burners[i]);
        }
        System.out.println(stringToPrint);
    }
    }