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); // 2024816일 (금)
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); // 2024816일 금요일
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();
    }
}