hyeonga_code

Java_59_API_스레드_생명 주기, 멀티 스레드, 메소드, 스레드 종류, 스케줄링 방식, 스레드 스케줄러, 동기화 본문

Java

Java_59_API_스레드_생명 주기, 멀티 스레드, 메소드, 스레드 종류, 스케줄링 방식, 스레드 스케줄러, 동기화

hyeonga 2023. 10. 24. 06:59
반응형


- Thread_스레드
          - 생명 주기
                    - NEW : 스레드가 만들어진 상태
                    - Runnable : 스레드 객체가 생성된 후에 start() 메소드 호출 시 이동합니다.
                    - Running : Runnable 상태에서 스레드 스케줄러에 의해 이동합니다.
                    - Blocked : 스레드가 다른 특정한 이유로 Running 상태에서 Blocked 상태로 이동합니다.
                    - Dead : 스레드 종료 시 다시 시작할 수 없습니다.
          - 멀티 스레드
                    - 하나의 프로그램 안에서 여러 개의 프로그램을 동시에 실행하도록 하는 것
                    - 프로세스 내에서 실행되는 세부 작업 단위입니다.
                                        - 멀티 프로세스 : 두 개 이상의 프로세스가 실행되는 것
                                        - 멀티 태스킹 : 두 개 이상의 프로세스를 실행하여 일을 처리하는 것
                    - 방법
                              - Thread 클래스 상속
                              - run 메소드를 오버라이드
                              - start 메소드를 실행
                    - 생성자
                              Thread()
                              Thread(Runnable target)
                              Thread(Runnable target, String name)
                              Thread(String name)
                    - 순서
                              1. Runnable 인터페이스 상속
                              2. run  메소드를 오버라이드
                              3. Thread 클래스 객체를 생성하는 데 그 때 매개 변수로 넣음
                              4. 새로 만든 Thread클래스의 start를 해주면 된다
          - 메소드
                    - sleep(long millis) : millis에 지정된 시간만큼 대기
                    - getName : 스레드 이름 반환
                    - setName(String name) : 스레드 이름 반환
                    - start() : 스레드 시작
                    - getPriority() : 스레드의 우선순위 반환
                    - setPriority(int newPriority) : 스레드 우선순위 지정
                    - join() : 현재 스레드는 join() 메소드를 호출한 스레드가 종료될 때까지 대기
                    - yield() : 수행중인 스레드 중 우선순위가 같은 다른 스레드에게 제어권을 넘김
                    - currentThread() : 현재 수행되는 스레드 객체를 리턴합니다.
          - 스레드 종류
                    - User Thread 
                              - main()의 종료와 상관없이 thread는 계속 실행됩니다.
                              - setDaemon(false)
                    - Daemon Thread
                              - main()의 종료 시 thread가 종료됩니다.
                              - setDaemon(true)
          - 스케줄링 방식
                    - 선점형 스레드 스케줄링
                              - 스레드의 우선권을 가지고 우선 순위가 높은 스레드를 먼저 수행시키는 방식
                    - 협력형 스레드 스케줄링
                              - 실행중인 스레드가 CPU 사용권을 다른 스레드에게 넘길 때까지 기다리는 방식
                    - JVM 
                              - 우선 순위에 따른 선점형 스레드 스케줄링 방식을 사용합니다.
                    - SJF_Shortest Job First
          - 스레드 스케줄러
                    - 멀티 스레드가 수행될 때 어떤 스레드가 먼저 수행될지는 스케줄러가 결정합니다.
                    - 자바 애플리케이션에서는 우선 순위가 높은 선점형 스레드 스케줄러를 사용합니다.
          - Thead에 관한 정보 알아내기
                    - 우선순위 결정(1-10)
                              setPriority(MIN_PRIORITY, NORM_PRIORITY, MAX_PRIORITY)
                    - main() 연관성
                              setDaemon(true/false)
                              - 반드시 start 이전에 설정해야 합니다.
                              Thread[] th = new Thread('개수');
                              Thread.enumerate(th); // Thread의 정보를 저장
          - 동기화
                    - 동시 접근을 방지합니다.
                    - 임계영역 : 멀티 스레드에의해 공유 자원이 참조될 수 있는 코드의 범위
                    - 멀티 스레드 프로그램에서 임계영역을 처리하는 경우 심각한 문제가 발생할 수 있습니다.
                    - 동기화를 처리하기 위해 모든 객체에 락_lock을 포함했습니다.
                              - lock
                                        - 공유 객체에 여러 스레드가 동시에 접근하지 못하도록 하기 위함입니다.
                                        - 모든 객체가 힙 영역에 생성될 때 자동으로 생성됩니다.
                              - 잘못 동기화 시키는 경우 Dead Lock 이 걸립니다.
                    - 동기화 방법
                              public synchronized void synchonizedMethod(){
                                        // 임계 영역 코딩
                              }
                              public void nomalMethod(){
                                        synchronized(동기화할 객체/클래스 이름){
                                                  // 임계영역 코딩
                                        }
                              }
          - 관련 용어
                    - Fairness_공정
                              - 여러 스레드가 하나의 컴퓨팅 자원을 사용하기 위해 동시에 접근하는 프로그램을 작성하는 경우 
                              - 모든 스레드는 공정하게 그 자원을 사용할 수 있습니다.
                    - Starvation_기아
                              - 하나 또는 그 이상의 스레드가 자원을 얻기 위해 Blocked 상태에 위치
                              - 자원을 얻을 수 없게 되면 다른 작업을 할 수 없습니다.
                    - Deadlock_교착 상태
                              - 두 개 이상의 스레드가 만족하지 못하는 상태로 계속 기다리는 경우 발생합니다.


 - Thread 클래스 상속
=====

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import java.util.*;
 
class MyThread05 extends Thread{
    public void run() {
        System.out.println("Run");
    }
}
 
public class ex0325 {
    public static void main(String[] args) {
        System.out.println("Run Main Class");
        MyThread05 th = new MyThread05();
        //th.run; // 단일 스레드
        th.start();
        // 멀티 스레드
        System.out.println("End Main Class");
        // Thread를 상속받은 객체를 새로운 스레드 영역에서 run 메소드를 실행
        /*
        Run Main Class
        End Main Class
        Run
         */
    }
}



 - Runnable
=====

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import java.util.*;
 
class MyThread06 implements Runnable {
    public void run() {
        System.out.println("Running MyThread06");
    }
}
public class ex0325 {
    public static void main(String[] args) {
        System.out.println("Run Main Class");
 
        MyThread06 mth = new MyThread06();
        Thread th2 = new Thread(mth);
        // Runnable을 상속받은 클래스는 start 메소드가 없음
        // Thread 클래스 객체를 생성할 때 Runnable 타입의 객체를 받아 Thread 객체를 만들 수 있음
        // 새로운 Thread 클래스를 선언, 새로운 Thread 클래스의 start 메소드를 실행하면 
        // Runnable을 상속받아 만든 클래스의 run 메소드를 새로운 Thread 영역에서 실행시킨다.
        th2.start();
        /*
        Run Main Class
        Running MyThread06
         */
    }
}




=====

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import java.util.*;
 
class MyThread extends Thread{
    public void run() {
        System.out.println("Info: " + MyThread.currentThread());
    }
}
 
public class ex0325 {
    public static void main(String[] args) {
        MyThread th = new MyThread();
        th.start();
        System.out.println(Thread.currentThread());
        /*
        Thread[main,5,main]
        Info: Thread[Thread-0,5,main]
         */
    }
}



=====

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import java.util.*;
import java.text.*;
 
class MyThread extends Thread {
    private Date date;
    private SimpleDateFormat sdf;
 
    public MyThread() {
        sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    }
 
    public void run() {
        //System.out.println("정보 : " + Thread.currentThread());
        while (true) {
            date = new Date();
            System.out.println("현재시각 : " + sdf.format(date));
            try {
                Thread.sleep(1000);    //밀리세컨드 단위로 숫자를 넣어준다
            }
            catch (InterruptedException e) {}
        }
    }
}
 
public class Exam_06 {
    public static void main(String[] args) {
        MyThread th = new MyThread();
        th.setDaemon(true);      //main이 끝나면 th객체는 끝난다
        //\th.setName("홍길동");
        //th.setPriority(10);
        //priority : 1~10 -> 1이 제일 느림, 10이 제일 빠름, 5가 default
        th.start();
        try {
            Thread.sleep(5000);    //밀리세컨드 단위로 숫자를 넣어준다
            th.join(5000);    //th객체를 5초간 실행시켜주세요
        }
        catch (InterruptedException e) {}
        //System.out.println(Thread.currentThread());
    }
}




join
=====

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package com.java.exam04;
 
class MyRunnableTwo implements Runnable {
    public void run() {
        System.out.println("run");
        first();
    }
    
    public void first() {
        System.out.println("first");
        second();
    }
    
    public void second() {
        System.out.println("second");
    }
}
 
public class JoinEx {
    public static void main(String[] args) {
        System.out.println(Thread.currentThread().getName() + " start");
        Runnable r = new MyRunnableTwo();
        Thread myThread = new Thread(r);
        myThread.start();
        try {
            myThread.join();
        } catch (InterruptedException ie) {
            ie.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + " end");
            /*
                main start
                run
                first
                second
                main end
             */
    }
    
    /** myThread가 멈출때까지 기다립니다.
    public static void main(String[] args) {
        System.out.println(Thread.currentThread().getName() + " start");
        Runnable r = new MyRunnableTwo();
        Thread myThread = new Thread(r);
        myThread.start();
//        try {
//            myThread.join();
//        } catch (InterruptedException ie) {
//            ie.printStackTrace();
//        }
        System.out.println(Thread.currentThread().getName() + " end");
            /
                main start
                main end
                run
                first
                second
             /
    }
     */
}




 - 업다운 게임, 소요시간 알림
=====

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import java.util.*;
 
class UpDownGame extends Thread{
    private int comsu;
    private Scanner in;
    private int time;
    private boolean isGame;
    
    public UpDownGame() {
        in = new Scanner(System.in);
        comsu = (int)(Math.random()*100+ 1;
        time = 0;
        isGame = true;
    }
    
    public void run() {
        while(isGame) {
            time++;
            try {
                Thread.sleep(1000);
            }catch(Exception e) {}
        }
    }
    
    public void gameStart() {
        this.start();
        while(true) {
            System.out.print("수를 입력 : ");
            int su = in.nextInt();
            if (su == comsu) {
                break;
            }else if (su < comsu) {
                System.out.println("Up");
            }else {
                System.out.println("Down");
            }
        }
        isGame = false;
        System.out.println(time+"초만에 맞추셨습니다.");
    }
}
 
 
public class Exam_07 {
    public static void main(String[] args) {
        UpDownGame game = new UpDownGame();
        //game.start();
        game.gameStart();
    }
}



반응형