100일 챌린지/빅데이터기반 인공지능 융합 서비스 개발자

Day18 - 날짜 type 제어하기, java.util 사용하기, Thread 활용하기

ksyke 2024. 8. 16. 12:43

목차

    java.util의 클래스들

    Calendar 사용하기

    public static String func1(int key) {
        String msg="월 ";
        switch(key) {
        case Calendar.JANUARY: msg = 1 + msg; break;
        case Calendar.FEBRUARY: msg = 2 + msg; break;
        case Calendar.MARCH: msg = 3 + msg; break;
        case Calendar.APRIL: msg = 4 + msg; break;
        case Calendar.MAY: msg = 5 + msg; break;
        case Calendar.JUNE: msg = 6 + msg; break;
        case Calendar.JULY: msg = 7 + msg; break;
        case Calendar.AUGUST: msg = 8 + msg; break;
        case Calendar.SEPTEMBER: msg = 9 + msg; break;
        case Calendar.OCTOBER: msg = 10 + msg; break;
        case Calendar.NOVEMBER: msg = 11 + msg; break;
        case Calendar.DECEMBER: msg = 12 + msg; break;
        default: break;
        }
        return msg;
    }
    
    public static void main(String[] args) {
        Calendar rightNow = Calendar.getInstance();
    
        rightNow.set(2002, 5-1, 1);
    
        System.out.print(rightNow.get(Calendar.YEAR) + "년 ");
        System.out.print(func1(rightNow.get(Calendar.MONTH)));
        System.out.print(rightNow.get(Calendar.DATE) + "일 "); // 16일
        System.out.print(rightNow.get(Calendar.DAY_OF_MONTH) + "일 "); // 16일
    
        System.out.println(Calendar.DAY_OF_WEEK);
        System.out.println(Calendar.WEEK_OF_MONTH);
        System.out.println(Calendar.WEEK_OF_YEAR);
    
        switch(rightNow.get(Calendar.AM_PM)) {
            case Calendar.AM: System.out.print("오전 ") ;break;
            case Calendar.PM: System.out.print("오후 ") ;break;
            default: break;}
        System.out.print(rightNow.get(Calendar.HOUR) + "시 "); // 0 ~ 11시
        System.out.print(rightNow.get(Calendar.MINUTE) + "분 ");
        System.out.print(rightNow.get(Calendar.SECOND) + "초 ||");
        System.out.print(rightNow.get(Calendar.HOUR_OF_DAY) + "시 "); // 0 ~ 23
        System.out.print(rightNow.get(Calendar.MINUTE) + "분 ");
        System.out.print(rightNow.get(Calendar.SECOND) + "초 ");
    }
    Calendar d1 = Calendar.getInstance();
    Calendar d2 = Calendar.getInstance();
    d2.set(2025, 0, 16);
    
    System.out.println(d1.before(d2)); // true
    System.out.println(d2.before(d1)); //false
    
    System.out.println(d1.compareTo(d2)); // -1
    System.out.println(d2.compareTo(d1)); // 1
    
    java.util.Date d3 = d2.getTime();
    System.out.println(d3); // Thu Jan 16 10:44:41 KST 2025
    
    long d4 = d2.getTimeInMillis();
    System.out.println(d4); // 1736991929940

    Gregorian Calendar

    TimeZone tz = TimeZone.getTimeZone("America/LosAngeles");
    GregorianCalendar cal1 = new GregorianCalendar(tz);
    System.out.print(cal1.get(Calendar.DATE));
    System.out.println(cal1.get(Calendar.HOUR_OF_DAY));
    
    GregorianCalendar cal2 = new GregorianCalendar(2002, 5-1, 1);
    System.out.print(cal2.get(Calendar.DATE));
    System.out.println(cal2.get(Calendar.HOUR_OF_DAY));

    java.util.Date

    DateFormat

    Date d1 = new Date();
    String myString = DateFormat.getDateInstance().format(d1);
    
    System.out.println(myString); // 2024. 8. 16
    
    DateFormat df1 = DateFormat.getDateInstance(DateFormat.DEFAULT); // 2024. 8. 16
    System.out.println(df1.format(d1));
    DateFormat df2 = DateFormat.getDateInstance(DateFormat.LONG); // 2024년 8월 16일 (금)
    System.out.println(df2.format(d1));
    DateFormat df3 = DateFormat.getDateInstance(DateFormat.SHORT); // 24. 8. 16
    System.out.println(df3.format(d1));
    DateFormat df4 = DateFormat.getDateInstance(DateFormat.FULL); // 2024년 8월 16일 금요일
    System.out.println(df4.format(d1));

    SimpleDateFormat

    Date d1 = new Date();
    SimpleDateFormat sdf = new SimpleDateFormat();
    String msg = sdf.format(d1);
    System.out.println(msg); // 24. 8. 16 오전 11:22
    
    SimpleDateFormat sdf2 = new SimpleDateFormat("yy/MM/dd hh:mm:ss");
    System.out.println(sdf2.format(d1)); // 24/08/16 11:25:38

    LocalDate

    LocalDate ld = LocalDate.now();
    System.out.println(ld); // 2024-08-16
    
    LocalDateTime ldt = LocalDateTime.now();
    System.out.println(ldt); // 2024-08-16T11:30:41.655
    
    LocalTime lt = LocalTime.now();
    System.out.println(lt); // 11:31:42.933
    
    LocalDate ldf = LocalDate.of(2002, 5, 1);
    System.out.println(ldf); // 2002-05-01

    java.util.Arrays

    int[] arr1 = new int[] {1, 3, 5, 7};
    
    System.out.println(arr1);
    System.out.println(Arrays.toString(arr1));
    
    int[] arr2 = Arrays.copyOf(arr1, arr1.length);
    arr1[0] = 2;
    System.out.println(Arrays.toString(arr2));
    
    int[] arr3 = Arrays.copyOfRange(arr1, 1, 3);
    System.out.println(Arrays.toString(arr3));
    
    Arrays.fill(arr1, 0);
    System.out.println(Arrays.toString(arr1));
    
    int[] arr4 = new int[] {1, 7, 5, 3};
    Arrays.sort(arr4);
    System.out.println(Arrays.toString(arr4));
    
    System.out.println(Arrays.binarySearch(arr4, 7)); // binarySearch를 하기 위해선 반드시 sort를 해야 한다. 
    
    List list = Arrays.asList(2, 4, 6, 8);
    System.out.println(list); // 리스트로 만들어준다.

    java.util.Random

    Random ran = new Random(1); // seed 값을 명세하면 실행할때마다 고정된 값을 얻을 수 있다. 
    System.out.println(ran.nextInt()); // Integer.MIN_VALUE ~ MAX
    System.out.println(ran.nextDouble()); // 0 <= value < 1
    System.out.println(ran.nextBoolean()); // true / false
    System.out.println(ran.nextInt(3)); // 0, 1, 2 (입력된 값보다 1 적은)

    java.util.Scanner

    File f = new File("target.txt");
    InputStream is = new FileInputStream(f);
    
    Scanner sc = new Scanner(is);
    int i = sc.nextInt(); // 개행, 탭 등을 기준으로 문자를 나눈다.
    System.out.println(i + 1);
    
    Scanner sc1 = new Scanner("target\ntxt");
    String msg = sc1.next();
    System.out.println(msg); // target
    msg = sc1.next();
    System.out.println(msg); // txt
    
    while(sc.hasNextLine()) {
        System.out.println(sc.next());
    }

    java.util.StringTokenizer

    String msg = "java,web,,database,framework";
    
    String[] arr1 = msg.split(",");
    System.out.println(Arrays.toString(arr1)); // [java, web, , database, framework]
    
    StringTokenizer stk = new StringTokenizer(msg);
    while(stk.hasMoreTokens()){
        String token = stk.nextToken(); // 값이 없는 value는 제외시킨다.
        System.out.println(token); // java,web,,database,framework
    }

    java.util.Properties

    Properties props = new Properties();
    props.setProperty("key1", "val1");
    props.setProperty("key2", "val2");
    props.setProperty("key3", "val3");
    
    System.out.println(props.getProperty("key1"));
    System.out.println(props.getProperty("key2"));
    System.out.println(props.getProperty("key3"));
    
    Properties props2 = System.getProperties();
    Set set = props2.entrySet();
    Iterator ite = set.iterator();
    while(ite.hasNext()) {
        System.out.println(ite.next());
    }
    System.out.println("--------");
    
    InputStream is = new FileInputStream(new File("target2_properties.txt"));
    Properties prop3 = new Properties();
    prop3.load(is);
    System.out.println(prop3.getProperty("key1"));
    System.out.println(prop3.getProperty("key2"));

    java.util.Base64

    String msg = "한글";
    byte[] arr1 = Base64.getEncoder().encode(msg.getBytes());
    System.out.println(new String(arr1)); // x9Gx2w==
    
    byte[] arr2 = Base64.getDecoder().decode("x9Gx2w==".getBytes());
    System.out.println(new String(arr2)); // 한글

    Thread : 병렬 처리

    • java에서 병렬 처리는 stack영역에 새로운 공간이 생기는 것이다(개념적으로). 그래서 main 클래스가 종료되도 java가 종료되지 않는다.

    THread의 생성 방법

    public class Ex14 extends Thread{
    
        @Override
        public void run() {
    //        Thread thr1 = this.currentThread();
    //        String name = this.getName();
    //        System.out.println(name);
            Thread thr2 = Thread.currentThread();
            System.out.println(thr2.getName()); 
        }
    
        public static void main(String[] args) {
            Thread thr = Thread.currentThread();
            System.out.println(thr.getName()); // main
            Ex14 me = new Ex14();
    //        me.run();
            me.start(); // Thread-0 - 새로운 스레드를 상속받아 호출
        }
    }
    • 병렬에서는 main이 종료한다고 코드가 종료되는것이 아니다. 스레드가 다 끝나야 종료된다.
    System.out.println("main start");
    Thread thr1 = new Thread() {
        @Override
        public void run() {
            Thread thr1 = Thread.currentThread();
            System.out.println(thr1.getName());
        }
    };
    Thread thr2 = new Thread() {
        @Override
        public void run() {
            Thread thr1 = Thread.currentThread();
            System.out.println(thr1.getName());
        }
    };
    
    thr1.start(); // Thread-0
    thr2.start(); // Thread-1
    
    System.out.println("main end");
    public class Ex15 implements Runnable{
    
        public static void main(String[] args) {
            System.out.println("main start");
            Thread thr1 = new Thread() {
                @Override
                public void run() {
                    Thread thr1 = Thread.currentThread();
                    System.out.println(thr1.getName());
                }
            };
            Thread thr2 = new Thread(new Ex15());
    
            Thread thr3 = new Thread(new Runnable() {
                @Override
                public void run() {
                    Thread thr1 = Thread.currentThread();
                    System.out.println(thr1.getName());
                }
            });
    
            Thread thr4 = new Thread(() -> System.out.println(Thread.currentThread().getName()));
    
            thr1.start(); // Thread-0
            thr2.start(); // Thread-1
            thr3.start(); // Thread-2
            thr4.start(); // Thread-3
    
            System.out.println("main end");
        }
    
        @Override
        public void run() {
            Thread thr1 = Thread.currentThread();
            System.out.println(thr1.getName());
        }
    }

    Frame을 사용하는것도 Thread를 이용하는 것과 같다.

    public class Ex17 extends Frame{
    
        public Ex17() {
            setBounds(0,0,500,400);
            setVisible(true);
            dispose();
        }
    
        public static void main(String[] args) {
            System.out.println("main start");
            Ex17 me = new Ex17();
            System.out.println("main end");
        }
    }
    public class Ex17 extends Frame{
    
        static Label la;
    
        public Ex17() {
            la = new Label();
            la.setFont(new Font("", 0, 20));
            add(la);
    
            setBounds(0,0,500,400);
            setVisible(true);
    //        dispose();
        }
    
        public static void main(String[] args) throws InterruptedException {
            Ex17 me = new Ex17();
    
            Thread thr = new Thread(new Runnable() {
                @Override
                public void run() {
                    for(int i = 0; i < 10; i ++) {
                        la.setText(LocalTime.now() + "");
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    me.dispose();
                }
            });
            thr.start();
        }
    }

    Thread의 제어

    Thread의 상태 확인하기

    public class Ex19 extends Thread{
        static Thread.State state;
    
        @Override
        public void run() {
            Thread thr = Thread.currentThread();
            state = thr.getState();
            for(int i = 0; i < 10000000; i++) new String(i + "");
    
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            for(int i = 0; i < 10000000; i++) new String(i + "");
        }
    
        public static void main(String[] args) {
            Ex19 me = new Ex19();
            Thread thr = new Thread(new Runnable() {
                @Override
                public void run() {
                    while(true) {
                        if(me.getState() == Thread.State.NEW) {
                            System.out.println("new");
                        }
                        if(me.getState() == Thread.State.RUNNABLE) {
                            System.out.println("runnable");
                        }
                        if(me.getState() == Thread.State.WAITING) {
                            System.out.println("waiting...");
                        }
                        if(me.getState() == Thread.State.TIMED_WAITING) {
                            System.out.println("sleep...");
                        }
                        if(me.getState() == Thread.State.TERMINATED) {
                            System.out.println("end");
                        }
                    }
                }
            });
            thr.start();
    
            me.start();
        }
    
    }

    우선순위

    public class Ex20 extends Thread{
    
        String name;
    
        public Ex20(String name) {
            this.name = name;
        }
    
        @Override
        public void run() {
            System.out.println(name + " : " + this.getPriority()); // 빈도수 확인하기
            for(int i = 0; i < 100; i++) {
                System.out.println(name + "working..." + i);
            }
        }
    
        public static void main(String[] args) {
            Ex20 me1 = new Ex20("첫번째");
            Ex20 me2 = new Ex20("두번째");
            Ex20 me3 = new Ex20("세번째");
    
            me1.setPriority(Thread.MAX_PRIORITY); // 10
            me2.setPriority(Thread.NORM_PRIORITY); // 5
            me3.setPriority(Thread.MIN_PRIORITY); // 1
    
            me1.start();
            me2.start();
            me3.start();
        }
    }

    병렬처리에서 일어나는 문제

    두 개의 스레드에 나눠서 1~100까지 더하기 (동기화 문제)

    public class Ex21 extends Thread{
        static int sum;
        int a, b;
    
        public Ex21(int a, int b) {
            this.a = a;
            this.b = b;
        }
    
        public void func(int a, int b) {
            for(int i = a; i <= b; i++) {
                sum += i;
            }
        }
    
        @Override
        public void run() {
            func(a, b);
            System.out.println(sum);
        }
    
        public static void main(String[] args) {
            Ex21 me1 = new Ex21(1, 500);
            Ex21 me2 = new Ex21(501, 1000);
    
    //        me1.run();
    //        me2.run(); // 문제 없음
    
            me1.start();
            me2.start(); // 스레드로 병렬 처리했을 때 숫자가 잘 더해지지 않는 문제점이 있다.
        }
    }

    => 공용 객체에 대한 접근에 대한 문제가 생긴다.

    method synchronize를 통해 문제 해결법

    • 특정 스레드가 들어와서 일을 하고 있는 동안은 다른 스레드가 들어오지 못한다.
    public static synchronized void func(int a, int b) {
        for(int i = a; i <= b; i++) {
            sum += i;
        }
    }

    code synchronize를 통한 문제 해결법

    static Object key = new Object();
    
    public void func(int a, int b) {
        synchronized(key) {
            for(int i = a; i <= b; i++) {
                sum += i;
            }
        }
    }
    public class Ex21 extends Thread{
        static int sum;
        int a, b;
    //    static Object key = new Object();
        Object key;
    
        public Ex21(int a, int b, Object key) {
            this.a = a;
            this.b = b;
            this.key = key;
        }
    
        public void func(int a, int b) {
            synchronized(key) {
                for(int i = a; i <= b; i++) {
                    sum += i;
                }
            }
        }
    
        @Override
        public void run() {
            func(a, b);
            System.out.println(sum);
        }
    
        public static void main(String[] args) {
            Object key = 1;
            Ex21 me1 = new Ex21(1, 500, key);
            Ex21 me2 = new Ex21(501, 1000, key);
    
            me1.start();
            me2.start();
        }
    }

    Frame으로 스레드 제어하기

    public class Ex22 implements Runnable {
        static Button[] btns;
    
        public static void main(String[] args) {
            Ex22 me = new Ex22();
            Thread thr = new Thread(me);
    //        thr.start();
            Frame f = new Frame();
            f.setLayout(new GridLayout(1, 4));
            btns = new Button[] {
                    new Button("start"),
                    new Button("stop"),
                    new Button("resume"),
                    new Button("suspend"),
            };
            f.setBounds(0, 0, 400, 100);
            f.setVisible(true);
    
            btns[0].addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    thr.start();    
                }            
            });
            btns[1].addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    thr.stop();    
                }            
            });
            btns[2].addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    thr.resume();    
                }            
            });
            btns[3].addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    thr.suspend();    
                }            
            });
    
            for(int i = 0; i < btns.length; i++) {
                f.add(btns[i]);
            }
    
        }
        @Override
        public void run() {
            while(true) {
                System.out.println("working...");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    waiting 중인 스레드 빠져나오게 하기

    public class Ex23 {
    
        public static void main(String[] args) throws InterruptedException {
            Thread thr = new Thread(new Runnable() {
    
                public synchronized void func() {
                    try {
                        this.wait();
                    } catch (InterruptedException e) {
                        // e.printStackTrace();
                    }                
                }
    
                @Override
                public void run() {
                    System.out.println("스레드 시작");
    
                    func();
    
                    System.out.println("스레드 종료");
                }
            });
    
            thr.start();
            Thread.sleep(1000);
            thr.interrupt(); // interrupt exception을 던져서 catch를 발동시켜 wait에서 빠져나온다.
        }
    }

    => interrupt로 일시중시를 하고 interrupt로 재시작하는 형태로 이용할 수 있다.

    notify/notifyAll로 wait으로 잠들어있는 스레드 깨우기

    public class Ex24 {
        static Thread me = new Thread(new Runnable() {
    
            public void run() {
                System.out.println("start");
                synchronized(me) {
                    try {
                        me.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("end");
            }
        });
    
        public static void func() {
            synchronized(me) {
                me.notify();
                me.notifyAll();
            }
        }        
    
        public static void main(String[] args) throws InterruptedException {
            me.start();
            Thread.sleep(5000);
            func();
        }
    }

    main으로 스레드 관리하기(main이 모든 스레드가 끝나기 전에 종료되지 않게 하기)

    public class Ex25 extends Thread{
    
        @Override
        public void run() {
            System.out.println(this.getName() + "start");
            System.out.println(this.getName() + "end");    
        }
    
        public static void main(String[] args) throws InterruptedException {
            System.out.println("main start");
            Ex25 me = new Ex25();
            me.start();
    //        me.join();
            me.join(1000);
            System.out.println("main end");
        }
    }

    종속된 스레드 (Daemon Thread)

    System.out.println("main start");
    Ex25 me = new Ex25();
    Ex25 me1 = new Ex25();
    me.setDaemon(true); // 종속돼있는 스레드를 만든다. 
    me1.setDaemon(true); // 메인 스레드가 종료되는 순간 종료된다.
    me.start();
    me1.start();
    me.join(1000);
    System.out.println("main end");

    Thread를 활용한 두더지 게임 만들기

    public class Ex06_answer extends Frame implements ActionListener{
        static JButton[] btns;
        static Panel center;
        int score, sec = 10;
        Label count, time;
        Button start;
    
        public Ex06_answer() {
            setLayout(new BorderLayout());
            Panel top = new Panel();
            Panel down = new Panel();
            center = new Panel();
            Panel right = new Panel();
    
            Font title = new Font("궁서체", Font.BOLD, 24);
    
            top.setLayout(new GridLayout(1, 2));
            Label ltitle = new Label("두더지 게임", Label.LEFT);
            ltitle.setFont(title);
            top.add(ltitle);
            time = new Label(sec + "초", Label.RIGHT);
            top.add(time);
    
            count = new Label(score + "점");
            down.add(count);
    
            right.setLayout(new GridLayout(4, 1));
            right.add(new Label());
            start = new Button("시작");
            start.addActionListener(this);
            right.add(start);
            Button exit = new Button("종료");
            exit.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    dispose();
                }
            });
            right.add(exit);
    
            center.setLayout(new GridLayout(4, 4));
            btns = new JButton[16];
            for(int i = 0; i < 16; i++) {
                btns[i] = new JButton();
                btns[i].setEnabled(false);
                if(i < 4) {
                    btns[i].addActionListener(new ActionListener() {
                        @Override
                        public void actionPerformed(ActionEvent e) {
                            score++;
                            count.setText(score + "점");
                        }
                    });
                    Icon icon = new ImageIcon("ball2.jpg");
                    btns[i].setIcon(icon);
                }else {
                    btns[i].addActionListener(new ActionListener() {
                        @Override
                        public void actionPerformed(ActionEvent e) {
                            score--;
                            score--;
                            count.setText(score + "점");
                        }
                    });
                    Icon icon = new ImageIcon("ball1.jpg");
                    btns[i].setIcon(icon);
                }
                center.add(btns[i]);
            }
    
            add(top, BorderLayout.NORTH);
            add(down, BorderLayout.SOUTH);
            add(center, BorderLayout.CENTER);
            add(right, BorderLayout.EAST);
            addWindowListener(new WindowAdapter() {
                @Override
                public void windowClosing(WindowEvent e) {
                dispose();
                }
            });
            java.awt.Toolkit kit = Toolkit.getDefaultToolkit();
            Dimension screen = kit.getScreenSize();
            int w, h;
            w = screen.width/2-(750/2);
            h = screen.height/2-(800/2);
            setBounds(w, h, 750, 800);
            setVisible(true);
        }
    
        public static void main(String[] args) {
            Ex06_answer me = new Ex06_answer();
    
    
        }
    
        Random ran = new Random();
        public void mix() {
            int end = sec;
            for(int j = 0; j < end; j++) {
                time.setText(--sec + "초");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                for(int i = 0; i < 100; i++) {
                    int su = ran.nextInt(15);
                    center.add(btns[su]);
                }
                this.validate();
            }        
            for(int i = 0; i < btns.length; i++) {
                btns[i].setEnabled(false);
            }
            start.setEnabled(true);
        }
    
        @Override
        public void actionPerformed(ActionEvent e) {
            sec = 5;
            score = 0;
            count.setText(score + "점");
            start.setEnabled(false);
            for(int i = 0; i < btns.length; i++) {
                btns[i].setEnabled(true);
            }
            Thread thr = new Thread(new Runnable() {
                @Override
                public void run() {
                    mix();
                }
            });
            thr.setDaemon(true);
            thr.start();
        }
    }