즐겁게!! 자신있게!! 살아보세!!

재밌는 인생을 위하여! 영촤!

Language_Study/JAVA

[JAVA, App] 14.기본API클래스

Godwony 2020. 12. 27. 12:01
반응형

Properties

  • Key 와 Value를 쌍으로 저장하는 자료구조
  • Map 은 모든 자료형을 사용할 수 있지만 Properties는 Key 와 Value 모두 String 만 가능
  • 자료형이 결정되어 있어서 앞에 나온 자료구조 들과 다르게 Generics을 이용하지 않습니다.
  • 환경설정을 xml 이나 텍스트 파일에 작성해두고 그 내용을 읽어서 프로그램에 적용하고자 하는 용도로 많이 사용
  • Spring 같은 프레임워크에서는 메시지 출력 등에 이용됩니다.

1.주요 메소드

  • String setProperty(String key, String value): 프로퍼티 저장

  • String getProperty(String key): key에 해당하는 프로퍼티를 가져옵니다.

  • void store(OutputStream stream, String comment): comment 와 함께 stream(파일이나 네트워크)에 내용을 저장

  • void storeToXML(OutputStream stream, String comment): comment 와 함께 stream에 XML 형식으로 저장

2.XML(eXtensible Markup Language): 태그 형식으로 표현하는데 해석을 브라우저가 하지 않고 개발자나 설정된 스키마가 해석하는 형식의 문서

  • 이전에 web에서 데이터를 전송하기 위한 표준으로 사용되었고 설정 파일에 많이 이용되었습니다.
  • HTML(View)은 비구조적이기고 느슨한 문법을 적용하지만 XML(Data)은 구조적이고 엄격한 문법을 제공

3.현재 작업디렉토리 사용

  • ./: 현재 작업 디렉토리, 생략하고 파일 경로만 적으면 현재 작업디렉토리에서 작업을 합니다.
    • 명령어를 입력할 때는 Mac에서는 ./를 생략하면 명령어가 없다고 나옵니다.

4.실습 - 프로퍼티를 만들고 저장하기: 프로젝트 디렉토리에서 파일 생성여부 확인

    public static void main(String[] args) {
        //프로퍼티를 저장할 수 있는 인스턴스를 생성하고 데이터를 저장
        Properties props = new Properties();

        //프로퍼티 저장
        props.setProperty("name", "베르캄프");
        props.setProperty("nation", "holland");

        //프러퍼티 나 맵(dictionary, hashtable 라고도 합니다.)
        //프로퍼티나 맵에 없는 key의 값을 주었을 때 동작 방식
        String name = props.getProperty("name");
        //자바는 없는 key를 사용하면 null
        String age = props.getProperty("age");

        System.out.println(name);
        System.out.println(age);

        //props를 현재 디렉토리에 temp.xml 파일로 내보내기
        try {
            props.storeToXML(new FileOutputStream("temp.xml"), "주석");
        }catch(Exception e) {
            System.out.println("예외발생:" + e.getMessage());
        }
    }

Collections 클래스

  • 자바의 자료구조들을 동기화 된 자료구조 와 변경 불가능한 자료구조로 변환해주는 클래스로 모든 메소드가 static으로 만들어져 있어서 인스턴스를 생성할 필요가 없고 모든 메소드가 매개변수를 대입된 데이터를 변경하지 않고 리턴을 합니다.
  • synchronized 가 붙으면 동기화 된 자료구조를 만들어주는 메소드
  • 동기화: 읽기를 하는데는 아무런 제한이 없지만 수정이나 삽입 및 삭제등의 작업을 할 때는 다른 스레드가 사용 중이면 작업이 종료될 때 까지 기다렸다가 수행
//동기화가 적용되지 않은 List
List <String> list = new ArrayList<String>();

List<String>syncList = Collections.synchronizedCollection(list);
//syncList는 동기화가 적용된 List
  • unmodifiable이 붙으면 변경이 불가능한 자료구조를 생성
final List <String> list = new ArrayList<String>();
//final이 붙은 경우는 list를 수정하지 못하는 것이지 list 안의 데이터를 수정 못하는 것이 아닙니다.
list = new ArrayList<String>(); //이 구문은 에러 list 자체를 변경할려고 해서 에러
list.add("Hello World"); //이 구문은 에러가 아님, list 내부를 수정하는 것은 가능

List <String> imList = Collections.unmodifiableCollection(list);
//imList는 내부 데이터를 수정하지 못합니다.
  • checked를 추가하면 1가지 데이터 타입만 사용이 가능
    • 이 부분은 제너릭을 적용하면 동일한 효과를 만들 수 있음
    • 제너릭을 적용하지 않고 만들어진 자료구조라면 이 메소드를 이용해서 제너릭을 적용하는 효과를 만들 수 있습니다.
    • 제너릭은 인스턴스를 만들 때 자료형을 결정하는 것으로 자료구조 클래스에서 주로 이용

List <String> list = new ArrayList<String>(); //list에는 String 만 저장 가능

List list1 = new ArrayList(); //list1에는 모든 자료형의 데이터를 저장할 수 있습니다.

  • 자동으로 Object 의 List가 됩니다.
  • 이런 경우 String 만 저장하도록 변경하고자 하는 경우에 checked를 사용

List list2 = Collections.checkedCollection(list1, String.class);

  • list2는 String 만 저장 가능

java.util.Random

  • 랜덤한 값을 생성해주기 위한 클래스
  • 랜덤한 값은 seed(난수표)에서 데이터를 순서대로 하나씩 가져오는 개념
    • seed가 고정이 되면 랜덤 값은 일정한 패턴으로 리턴됩니다.

1.생성자

  • Random(): 현재 시간을 기준으로 해서 seed를 설정, 생성될 때 마다 seed 가 변경될 가능성이 높음
  • Random(long seed): seed를 매개변수로 설정

2.메소드

  • float nextFloat(): 실수형 난수 생성해서 리턴
  • int nextInt: 정수형 난수 생성
  • int nextInt(int n): %n 한 결과의 난수를 생성
  • void setSeed(long seed): seed를 변경

3.java.util.UUID 클래스

  • 이 클래스의 static 메소드인 randomUUID()를 호출하면 랜덤한 문자열을 생성
    • 결과를 toString()으로 확인하면 랜덤한 문자열을 확인할 수 있습니다.

4.랜덤 실습1

    public static void main(String[] args) {
        //seed 설정 없이 랜덤 인스턴스 생성 - seed 가 현재 시간을 설정
        Random r1 = new Random();
        //seed를 1번으로 설정
        Random r2 = new Random(1);

        //실행할 때 마다 다르게 나옴
        int result1 = r1.nextInt();
        //실행할 때 마다 동일하게 나옴
        int result2 = r2.nextInt();

        System.out.println("result1:" + result1);
        System.out.println("result2:" + result2);

        //빨강, 파랑, 녹색 을 랜덤하게 출력
        //랜덤하게 출력되는 것에 제한을 가하기 위한 배열을 생성
        String [] colors = {"머니", "머니", "아이템1", "아이템2", "아이템3"};
        //배열에서 배열안의 인덱스가 랜덤하게 나오도록 r1.nextInt(colors.length)
        //배열의 인덱스에 적용
        for(int i=0; i<10; i=i+1) {
            String color = colors[r1.nextInt(colors.length)];
            System.out.println("color:" + color);
        }

        //비복원 추출 - 훈련데이터 와 테스트데이터 샘플링, 로또, 고스톱, 포커
        List<String> list = new ArrayList<String>();
        //1-45까지 저장
        for(int i=1; i<=45; i=i+1) {
            list.add(i + "");
        }
        //20개의 숫자를 비복원 추출
        for(int i=0; i<20; i=i+1) {
            //list 사이즈 내에서 데이터를 추출
            String x = list.get(r1.nextInt(list.size()));
            //그 데이터를 제거
            list.remove(x);
            System.out.print(x + "\t");
        }
    }

5.랜덤 실습2

    public static void main(String[] args) {
        String [] image = {"!", "@", "#", "$", "%", "^"};
        //Random 객체 생성
        Random r = new Random();
        List<String> list = new ArrayList<String>();

        for(int i=0; i<3; i=i+1) {
            String temp = image[r.nextInt(image.length)];
            System.out.print(temp);
            list.add(temp);
        }
        System.out.print("\n");

        if(list.get(0) == list.get(1) && list.get(1) == list.get(2)) {
            System.out.println("3개가 모두 일치");
        }else if(list.get(0) == list.get(1)) {
            System.out.println("앞의 2개가 일치");
        }else {
            System.out.println("꽝");
        }

        //랜덤한 문자열 만들기 - 이미지 파일 등을 업로드 했을 때 파일이름 그리고 유저를 구분하기 위한 이름
        //등을 만들 때 이용
        String name = UUID.randomUUID().toString();
        System.out.println(name);
    }

날짜 관련 클래스

1.java.util.Date 클래스

  • 날짜와 시간을 저장하기 위한 클래스

1) 생성자

  • Date(): 현재 날짜 및 시간을 가지고 생성

  • Date(long timeMillis): 1970년1월1일 자정 이후부터 지나온 시간을 밀리초 단위로 입력해서 생성

  • Date(int year, int month, int day): 년월일을 입력해서 생성, 년도는 1900년 이후에 지나온 시간, 월은 0부터 시작하기 때문에 하나 적게 설정, day는 일반적인 형태로 설정
    2020년 1월 17일 : new Date(120, 0, 17)

  • Date(int year, int month, int day, int hour, int minute, int second): 년월일 시분초를 입력해서 생성

2) 주요 메소드

  • String toString(): 년월일 시분초를 문자열로 리턴

  • int get?(): ?에 해당하는 값을 정수로 리턴, deprecated

3) Java에서 데이터베이스 연동하는 프레임워크들이 데이터베이스의 Date 나 Time 과 매핑할 때 java.util.Date, java.sql.Date, java.sql.Time 등을 지원

  • 최근에는 java.util.Date 보다는 java.sql.Timestamp 사용을 권장

2.java.util.Calendar

  • 날짜와 시간을 저장하는 추상 클래스
    1) 인스턴스 생성
  • static Calendar getInstance()를 이용하면 현재 날짜 및 시간을 갖는 인스턴스를 생성해서 리턴
    • Calendar 클래스를 상속받은 클래스를 anonymous로 만들어서 인스턴스를 생성

2) 주요 메소드

  • long getTimeInMillis(): 1970년 1월 1일 자정이후에 지나온 시간을 밀리초 단위로 리턴

  • int get(Calendar의 field summary): field summary에 해당하는 값을 리턴

  • void set(Calendar의 field summary, int value): field summary에 해당하는 값을 value로 설정

3) Calendar 를 상속받은 GregorianCalendar 클래스도 있음

4) 상위 클래스나 인터페이스를 만드는 목적 중의 하나가 동일한 작업을 수행하는 클래스들의 메소드 이름을 확정하기 위해서 만듭니다.

  • List 인터페이스, Set 인터페이스, Map 인터페이스, Calendar 인터페이스가 대표적입니다.
Calendar cal = new GregorianCalendar(); //이 방식을 권장
GregorianCalendar cal = new GregorianCalendar();

3.Anonymous Class - 익명 클래스

  • 클래스나 인터페이스를 상속받아서 인스턴스를 만들 때 상속받는 클래스를 만들지 않고 인스턴스를 바로 생성하는 문법
  • 어떤 클래스나 인터페이스를 상속받아서 사용하는 것이 1번 뿐이라면 상속받는 클래스를 만드는 것은 자원의 낭비
    • 클래스나 인터페이스는 한 번 만들어지면 메모리에서 소멸되지 않습니다.
  • List 의 데이터를 정렬할 때 sort 메소드에 매개변수로 Comparator<E> 인터페이스를 대입해야 합니다.
    • 인터페이스이므로 인스턴스 생성을 못하기 때문에 sort 메소드에 대입을 할려면 상속을 받는 클래스를 만들고 인스턴스를 만들어서 대입해야 합니다.

4.날짜 클래스 사용

    public static void main(String[] args) {
        //java.util.Date 는 년도는 1900년 이후 지나온 년도, 월은 0부터 시작, 일은 1부터 시작
        //2020년 1월 17일을 만들고자 하는 경우
        //Date date = new Date(2020, 1, 17); //3920년 2월 17일이 됩니다.
        Date date = new Date(120, 0, 17);
        System.out.println(date);


        //Calendar 클래스의 인스턴스를 생성
        //Calendar 클래스는 추상 클래스 - 추상 클래스는 인스턴스를 생성할 수 없습니다.
        //이렇게 작성을 하면 Calendar 클래스의 인스턴스를 만드는 것이 아니고
        //Calendar 클래스를 상속받은 클래스의 Anonymous Class를 생성해서 인스턴스를 만든 후 리턴
        //자바에서 인터페이스나 추상클래스를 리턴타입으로 하는 모든 메소드는 이 원리가 적용됩니다.
        Calendar cal = Calendar.getInstance();
        //toString이 너무 많은 양의 데이터를 리턴하도록 만들어져서 보기 어려움
        //System.out.println(cal);

        //필요한 데이터만 추출 - 월은 0부터 시작하기 때문에 출력할 때는 +1
        System.out.println(cal.get(Calendar.MONTH) + 1);

        //1월 부터 12월 까지의 날 수를 배열에 저장
        //int [] months = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        //2월의 날수
        //months[1];

        //프로그래밍의 편리성을 위해서 첫번째 위치에 의미없는 값을 삽입해서
        //인덱스와 데이터의 위치를 맞추는 경우가 있습니다.
        int [] months = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        //2월의 날수
        //months[2];
    }

5.SimpleDateFormat

  • Format으로 끝나는 클래스는 java.text 패키지에 존재하고 서식에 맞춘 문자열을 만들어주는 클래스
  • DecimalFormat(숫자를 문자열), ChoiceFormat(실수 구간을 문자열로 - 숫자 데이터를 범주형으로 만들기), MessageFormat(폼에 데이터를 삽입) 등이 있습니다.

java.util.Scanner 클래스

  • 입력 스트림으로부터 데이터를 읽어내기 위한 클래스

    1.생성자

  • Scanner(InputStream is) : is로 부터 데이터를 읽어 내기 위한 Scanner 객체를 생성
  • 키보드 스트림: System.in

2.주요 메소드

  • int nextInt(): Enter 나 공백 앞까지 읽어서 정수로 변환한 후 리턴

    • Enter 나 공백 앞에 정수로 변환할 수 없는 데이터가 있으면 예외를 발생
  • String next(): Enter 나 공백 앞까지 읽어서 문자열로 변환한 후 리턴

    • 공백 앞 까지 읽다보니 중간에 공백을 포함한 문자열은 나누어서 읽게 됩니다.
  • `String nextLine()* : Enter 까지 읽어서 문자열로 변환한 후 리턴

  • double nextDouble(): 실수로 변환해서 리턴

  • void close(): Scanner 닫기, 이 메소드를 호출하지 않으면 메모리 정리가 이루어지지 않는다고(memory leak) 경고 발생

3.콘솔에서 키보드 입력의 문제점

  • 키보드 입력을 하게되면 입력한 내용 전체를 버퍼에 저장
  • 키보드 입력을 읽어가는 메소드들은 버퍼에서 필요한 만큼 가져가서 수행을 합니다.
  • 숫자 데이터를 입력받고 바로 이어서 문자열을 입력받는 경우에 문제가 발생할 수 있는데 그 이유가 숫자를 입력하고 Enter를 눌러서 숫자 입력을 종료하게 되는데 숫자 데이터를 가져가는 메소드는 Enter는 버퍼에 남겨두고 가져갑니다.
    • nextLine 메소드는 버퍼에 Enter가 남아있기 때문에 새로운 입력을 받지 않고 Enter를 가지고 가서 자신의 입력을 종료시킵니다.
  • 이런 경우에 버퍼를 비울 수 있는 메소드가 있다면 버퍼를 비우고 입력을 받고 버퍼를 비울수 없다면 Enter를 입력받을 수 있는 메소드를 호출해주면 됩니다.
    • 자바에서는 숫자 다음에 문자열을 입력받는 경우 입력받기 전에 Scanner.nextLine()을 호출해서 버퍼의 Enter를 삭제시킵니다.

C언어는 버퍼를 비울 수 있기 때문에 버퍼 비우는 함수를 호출한 후 다시 입력받고 파이썬 경우는 문자열을 입력받는 input() 만 제공

Thread

  • Program: 유사한 작업을 위한 file 의 집합

  • Process: 실행 중인 프로그램

    • Process는 자신의 작업이 수행 중인 동안 쉬는 시간이 생기더라도 다른 프로세스에게 제어권을 넘기지 않습니다.
    • 일반적인 함수나 메소드를 호출하는 것이 Process 입니다.
  • Thread: Process의 일부분으로 자원할당과 실행의 단위

    • 독자적으로 실행할 수 는 없고 Process의 일부분으로만 실행 가능
    • 한 번 실행하고 종료되면 재시작이 안됩니다.
    • 자신의 작업이 실행 중인 동안 일정 시간 단위 또는 쉬는 시간이 생기면 다른 스레드에 제어권을 넘길 수 있습니다.
    • 동시에 실행되는 것이 아니고 제어권을 넘겨서 다른 작업도 할 수 있다는 개념입니다.
  • Task: Process 와 Thread

1.여러 개의 Thread를 동시에 실행시켰을 때의 장점

  • 일반적으로는 작업의 처리 속도가 빨라집니다.
  • 자원을 효율적으로 사용할 수 있습니다.

2.여러 개의 Thread를 동시에 실행시켰을 때의 단점

  • 여러 개의 Thread가 공유자원을 동시에 수정할려고 하는 부분을 제어해야 해서 복잡해 질 수 있음
  • 너무 많은 Thread를 생성해서 실행하면 Thread 간의 이동하는 시간이 작업시간보다 길어져서 오히려 느려지는 현상이 발생할 수 있습니다.(Thrashing)

3.java.lang.Thread 클래스

  • Thread를 위한 클래스
    1) 생성자
  • Thread(): 스레드의 이름을 jvm이 설정
  • Thread(String name): 스레드 이름을 name으로 설정해서 생성
  • Thread(Runnable r): r을 가지고 스레드를 생성
  • Thread(Runnable r, String name): r을 가지고 스레드를 생성하고 이름은 name으로 설정

2) 메소드

  • static void sleep(int msec) throws InterruptedException

    • 현재 스레드를 msec 만큼 대기시키는 메소드
    • 사용을 할 때 InterruptedException을 처리 해 주어야 합니다.
  • void run(): 스레드로 수행할 내용을 가지는 메소드

  • void start(): 스레드로 실행하도록 하는 메소드

  • getName(), setName(String name): 스레드 이름 가져오기와 설정

  • getPriority(), setPriority(int priority): 스레드의 우선 순위 가져오기와 설정

  • isAlive(): 실행 중인 상태인지 확인할 수 있는 메소드

4.Runnable 인터페이스

  • public void run(): 스레드로 수행할 내용을 가지는 메소드

5.스레드를 만들고 실행

1) Thread 클래스를 상속하는 방법

  • Thread 클래스를 상속받는 클래스를 만들고 스레드로 수행할 내용을 run 메소드에 작성
  • 앞에서 만들어진 클래스의 인스턴스를 만들고 start()를 호출

2) Runnable 인터페이스를 구현하는 방법

  • Runnable 인터페이스를 implements 한 클래스를 만들고 스레드로 수행할 내용을 run 메소드에 작성
  • 앞에서 만든 클래스의 인스턴스를 생성
  • 앞에서 만든 인스턴스를 Thread 클래스의 생성자에 대입해서 Thread 클래스의 인스턴스를 만들고 start()를 호출

3) 스레드로 동작해야 하는 필수적인 작업은 네트워크 작업입니다.

  • 안드로이드나 iOS는 네트워크 전송에 스레드를 사용하지 않으면 에러

4) 스레드 생성 및 실행 실습

//하나의 파일에 클래스를 2개 만든 다면 
//public class는 1개이어야 하고 파일이름은 public class의 이름이어야 합니다.

//Runnable 인터페이스를 implements 한 클래스
class RunnableImpl implements Runnable{
    //스레드로 수행할 내용을 가지는 메소드
    public void run() {

    }
}

public class Main2 {

    public static void main(String[] args) {
        RunnableImpl r1 = new RunnableImpl();

        //r1 과 r2는 같은 기능
        Runnable r2 = new Runnable() {
            public void run() {
                //Hello Runnable 을 1초마다 5번 출력
                try {
                    for(int i=0; i<5; i=i+1) {
                        Thread.sleep(1000);
                        System.out.println("Hello Runnable");
                    }
                }catch(Exception e) {
                    System.out.println("스레드 예외:" + e.getMessage());
                }
            }
        };

        //Thread 클래스의 인스턴스를 생성
        Thread th = new Thread(r2);
        //r2의 run 메소드를 스레드로 수행
        th.start();

        Thread th1 = new Thread() {
            public void run() {
                //Hello Thread 을 1초마다 5번 출력
                try {
                    for(int i=0; i<5; i=i+1) {
                        Thread.sleep(1000);
                        System.out.println("Hello Thread");
                    }
                }catch(Exception e) {
                    System.out.println("스레드 예외:" + e.getMessage());
                }
            }
        };
        //스레드로부터 상속을 받은 경우에는 바로 start() 호출
        th1.start();
    }
}

6.스레드 상태 및 수명주기

1) new: 스레드가 만들어지고 실행 대기 중인 상태 - start를 호출하고 실행 대기

2) runnable: 실행 중인 상태

3) waiting: 대기 중인 상태인데 이 때는 다른 스레드가 notify() 나 notifyAll()을 호출해주면 다시 실행

4) timed_waiting: 자신의 실행 시간이 오기를 기다리고 있는 상태, 일정 시간 단위로 작업을 수행하는 time sharing system 에서 자신의 차례를 기다기고 있는 상태

5)block: 입출력 요청이 있는 경우 요청을 처리하기 위해서 cpu를 사용할 필요가 없기 때문에 block 상태로 작업을 수행하다가 입출력 요청이 끝나면 cpu에 알려서 작업을 계속 수행할 수 있는 상태

6)terminated: thread가 종료된 상태

  • run 메소드의 수행이 종료되었거나 다른 스레드에 의해서 강제로 종료된 경우

스레드는 한 번 종료되면 다시 실행시킬 수 없습니다.

7.Daemon Thread

  • Daemon Thread가 아닌 스레드가 하나도 없으면 자동으로 실행을 중지하는 스레드

  • 일반 스레드의 보조적인 역할을 수행하는 스레드

  • 일반 스레드는 자신의 run 메소드가 종료되거나 다른 스레드에서 강제로 종료시키지 않으면 자신의 작업을 계속 수행합니다.

    • 다른 스레드에서 예외가 발생해도 자신의 작업은 계속 수행합니다.
  • 대표적인 데몬 스레드로는 main 메소드, 일반 응용 프로그램에서 임시 저장 기능 이나 네트워크 프로그램에서 중간 중간 commit 하는 작업 등이 있습니다.

  • 데몬 스레드를 만드는 방법은 start()를 호출하기 전에 setDaemon(true)롤 호출하면 됩니다.

  • 데몬을 설정했을 때와 그렇지 않을 때의 수행 내용을 비교해보아야 합니다.

public static void main(String[] args) {
        Thread th = new Thread() {
            public void run() {
                try {
                    for(int i=0; i<10; i=i+1) {
                        Thread.sleep(1000);
                        System.out.println("데몬 스레드");
                    }
                }catch(Exception e) {

                }
            }
        };
        //th를 데몬으로 설정 - 다른 작업이 없으면 자동으로 종료
        //프로그램에서는 데몬 스레드가 더 많이 사용됩니다.
        //start 하기 전에 데몬으로 설정
        th.setDaemon(true);

        th.start();
        //th.setDaemon(true);

        try {
            Thread.sleep(3000);
        }catch(Exception e) {
            System.out.println(e.getMessage());
        }
        System.out.println("메인 종료");
    }

8.스레드의 우선 순위

  • 2개 이상의 스레드가 동작 중인 경우 어떤 스레드가 먼저 수행될 지 또는 자주 수행될지는 알 수 없습니다.
  • 이런 특정 스레드를 먼저 또는 자주 수행하도록 할 수 있는 기능이 우선순위 부여입니다.
    • 우선순위를 설정하도라도 반드시 우선순위에 따라 동작하지 않습니다.
    • 확률적으로 우선순위가 높으면 먼저 또는 자주 수행되는 것입니다.
  • 우선 순위를 가져오는 메소드가 int getPriority() 이고 우선순위를 설정하는 메소드가 void setPriority(int priority)
  • setPrority의 매개변수는 정수를 대입받도록 되어 있지만 실제로는 Thread 클래스의 Field Summary 인 MAX_PRIORITY, NORM_PRIORITY, MIN_PRIORITY를 설정하도록 합니다.
  • 위처럼 설정하라고 하는 이유는 2가지 인데 첫번째는 우선순위는 일정한 범위가 있습니다.
    • 아무 정수나 대입하면 안됩니다.
    • 두번째 이유는 스레드의 우선순위 범위는 운영체제마다 다릅니다.
    • 윈도우는 1-10까지 이고 UNIX에서는 1-7까지 입니다.
    • 10이라는 숫자를 대입하면 윈도우에서는 있는 범위 내의 숫자이기 때문에 아무런 문제가 되지 않지만 UNIX에서는 없는 숫자가 됩니다.
    • Thread.MAX_PRIORITY 로 설정하면 jvm이 알아서 windows에서 10 UNIX에서는 7로 설정을 합니다.
    • 자바가 모든 운영체제에서 동작하는 애플리케이션을 한 번만 제작해도 되는 이유는 java의 옵션들을 사용한다면 값은 jvm이 운영체제 별로 알아서 할당을 합니다.
    • jdk(개발도구) 자체는 운영체제 별로 분류가 되어 있지 않지만 실행을 해주는 jvm이 운영체제 별로 별도로 존재해서 jvm이 알아서 옵션 값들을 설정합니다.
  • Field Summary는 메소드들에서 사용하기 위한 옵션 값들입니다.
//class 를 만드는 경우는 대부분 인스턴스를 2개 이상 만드는 경우
class Threadext extends Thread{
    public void run() {
        //스레드 자신의 이름을 10번 출력(1초마다 쉬면서)
        for(int i=0; i<10; i=i+1) {
            try {
                Thread.sleep(1000);
                System.out.println(getName());
            }catch(Exception e) {}
        }
    }
}

public class Main4 {

    public static void main(String[] args) {
        Threadext th1 = new Threadext();
        Threadext th2 = new Threadext();
        Threadext th3 = new Threadext();

        //스레드 우선 순위 설정 : 확률적으로 th3 이 먼저 시작할 가능성이 높아집니다.
        th1.setPriority(Thread.MIN_PRIORITY);
        th2.setPriority(Thread.NORM_PRIORITY);
        th3.setPriority(Thread.MAX_PRIORITY);

        th1.start();
        th2.start();
        th3.start();

    }

}

9.스레드의 강제 종료

  • 스레드를 강제로 종료할 때는 스레드 인스턴스가 interrupt()라는 메소드를 호출해주면 되는데 이 때 스레드의 run 메소드에 InterruptedException이 발생했을 때 run 메소드를 종료하도록 코드를 만들어주어야 합니다.

  • Threadext 클래스에서 catch 구문에서 return을 생략하고 실행해보고 return을 넣고 실행

    • 두번째 스레드의 이름인 thread-1 이 계속 출력되기도 하고 3초 후에 출력이 안되기도 합니다.
    • return 이 있고 없고에 따라서 스레드가 강제로 종료되기도 하고 그렇지 않기도 합니다.
//class 를 만드는 경우는 대부분 인스턴스를 2개 이상 만드는 경우
class Threadext extends Thread{
    public void run() {
        //스레드 자신의 이름을 10번 출력(1초마다 쉬면서)
        for(int i=0; i<10; i=i+1) {
            try {
                Thread.sleep(1000);
                System.out.println(getName());
            }
            //InterruptedException이 발생했을 때 return 하도록 만들어주면 스레드가
            //강제로 종료될 수 있습니다.
            catch(InterruptedException e) {
                return;
            }
        }
    }
}

public class Main4 {

    public static void main(String[] args) {
        Threadext th1 = new Threadext();
        Threadext th2 = new Threadext();
        Threadext th3 = new Threadext();

        //스레드 우선 순위 설정 : 확률적으로 th3 이 먼저 시작할 가능성이 높아집니다.
        th1.setPriority(Thread.MIN_PRIORITY);
        th2.setPriority(Thread.NORM_PRIORITY);
        th3.setPriority(Thread.MAX_PRIORITY);

        th1.start();
        th2.start();
        th3.start();

        try {
            Thread.sleep(3000);
            //th2 스레드에게 인터럽트 발생
            th2.interrupt();
        }catch(Exception e) {}

    }

}

10.Thread의 실행 제어

  • void join(int millis, int nanos): 입력한 시간동안만 스레드를 수행

    • 윈도우즈와 같은 클라이언트 운영체제에서는 1/20 초 이하의 설정은 의미가 없습니다.
  • void suspend(): 작업을 일시 정지

  • void resume(): 일시 정지된 스레드가 작업을 계속

  • void yield(): 실행 상태를 양보하고 대기 상태로 전환

11.ThredGroup

  • Thread를 묶어서 관리하기 위한 클래스
  • 몇 몇 메소드가 특정 운영체제에서 제대로 동작하지 않아서 비추천
  • List 등을 이용해서 그룹화하기를 권장
반응형

'Language_Study > JAVA' 카테고리의 다른 글

[JAVA, App] 16.이벤트처리  (0) 2020.12.27
[JAVA, App] 15.MutualExclusion  (0) 2020.12.27
[JAVA, App] 13.Framework  (0) 2020.12.25
[JAVA, App] 12.Interface  (0) 2020.12.25
[JAVA, App] 11.Package  (0) 2020.12.25