ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Java | Thread (2) Thread 생성 & Multi Thread
    JAVA/JAVA 2020. 2. 10. 17:38

    Thread 생성 ①_Thread 클래스 상속 (권장)

    1. Thread 클래스 상속: start() 메소드를 사용하기 위함
    2. run() 메소드 작성: 스레드가 실행할 기능 작성
    3. 스레드 객체 생성
    4. start() 메소드로 스레드 실행

    예제

    import java.lang.Thread;
    
    public class MultiThread extends Thread {
    
        // 생성자
        public MultiThread(String s) {
            // 부모 생성자 호출
            super(s);
        }
    
        // Thread 클래스를 상속받아서 run() 구현
        public void run() { // 실시간으로 데이터 출력, 저장, 계산 etc.
            // a ~ z까지 출력하는 반복문
            for (char i = 'a'; i <= 'z'; i++) {
                // sleep() 메소드를 사용하기 위해 try~catch문으로 예외 처리
                try {
                    // 스레드가 2초 중지하도록 함
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(i);
                System.out.println("현재 실행중인 스레드: " + this.getName());
            }
        }
    
        public static void main(String[] args) {
            // MultiThread 스레드 객체 생성, 스레드 이름을 TEST로 설정
            MultiThread mt = new MultiThread("TEST");
    
            // 스레드 객체 실행
            mt.start();
    
            /* a
            현재 실행중인 스레드: TEST
            b
            현재 실행중인 스레드: TEST
            ...
            */
        }
    
    }

    Thread 생성 ②_Runnable 인터페이스 구현

    ※ Thread 클래스를 상속하는 것이 가장 좋지만
    다른 클래스도 상속받아야 하는 경우
    다중 상속이 불가능하기 때문에 Runnable 인터페이스를 구현

    1. Runnable 인터페이스 구현 클래스 작성
    2. Thread 클래스 객체 생성
    3. Thread 클래스 객체 생성시, 생성자의 인자로 Runnable 구현 클래스 전달
    4. Thread 객체에서 start() 메소드 호출

    Runnable Method

    메소드 설명
    void run() Runnable 인터페이스를 구현해서 Thread 생성시 구현해야 하는 메소드
    해당 스레드에서 실행해야 하는 코드 작성

    ※ Runnable 인터페이스에는 run()메소드만 존재하기 때문에 Thread 클래스를 상속받는 것이 가장 좋음


    예제

    import java.lang.Thread;
    
    // Runnable 인터페이스 구현
    public class MyThread implements Runnable {
    
        // run() 메소드 오버라이딩
        public void run() {
            while (5 > 1) {
                // "is Running!" 출력
                System.out.println("is Running!");
                try {
                    // 스레드가 1초간 정지하도록 함
                    Thread.sleep(1000);
                    // 현재 실행중인 스레드의 이름 출력
                    System.out.println(Thread.currentThread().getName());
                } catch (Exception e) {
                    System.out.println(e);
                }
            }
        }
    
        public static void main(String[] args) {
            // Runnable 구현 클래스 객체 생성
            MyThread mt = new MyThread();
    
            // Runnable 구현 클래스 객체를 이용해서 Thread 클래스 객체 생성, Thread 이름은 "Test"
            Thread tt = new Thread(mt, "Test");
    
            // tt 객체 실행
            tt.start();
    
            /*
            is Running!
            Test
            ....
            */
    
            // Runnable 구현 클래스 객체 실행, start() 메소드가 없음
            mt.run();
    
            /*
            is Running!
            main
            */
    
        }
    
    }

    Multi Thread 다중 스레드

    하나의 프로세스(프로그램)에 둘 이상의 스레드를 생성해서 실행

    스레드는 서로 경쟁적으로 실행됨


    장점

    • 하나의 프로그램으로 동시에 여러 작업 수행 가능
      동기화: 데이터를 공유해서 작업하므로 시스템을 효율적으로 사용 가능
    • 메모리 공유로 인한 시스템 자원 소모 감소

    단점

    • 서로 자원을 소모하다가 충돌할 가능성 존재
    • 코딩이 난해해져 버그 발생 확률이 높아짐

    예제

    import java.lang.Thread;
    
    // 첫 번째 스레드
    class PrintThread extends Thread {
    
        public void run() {
            // sleep() 사용을 위한 예외 처리
            try {
                // 1부터 9까지의 수 출력
                for (int i = 1; i < 10; i++) {
    
                    /*
                     스레드를 1~1000 밀리초만큼 무작위로 중지시킴,
                     Math.random(): 0 ~ 0.999999... 사이의 난수 반환
                     */
                    long sleepTime = (long) Math.ceil(Math.random() * 1000);
                     // 스레드 대기 시간 출력
                    System.out.println(sleepTime);
    
                    // 임의의 시간만큼 스레드를 중지시킴
                    this.sleep(sleepTime);
                    System.out.println("i: " + i);
                }
            } catch (Exception e) {
                System.out.println(e);
            }
        }
    }
    
    // 두 번째 스레드, 구구단 출력
    class GuguThread implements Runnable {
    
        // 단을 입력 받을 멤버 변수
        int dan;
    
        // 생성자
        public GuguThread(int dan) {
            this.dan = dan;
        }
    
        // 99단 출력 run() 메소드
        public void run() {
            for (int i = 1; i <= 9; i++) {
                System.out.println(dan + "X" + i + "= " + (dan * i));
                // 단을 하나씩 출력할 때마다 500밀리초씩 스레드를 중지시킴
                try {
                    Thread.sleep(500);
                } catch (Exception e) {
                    System.out.println(e);
                }
            }
    
        }
    }
    
    public class MultiThread2 {
    
        public static void main(String[] args) {
            // Runnable 구현 클래스 객체 생성
            GuguThread gu = new GuguThread(5);
    
            // gu 스레드 객체를 이용해서 Thread 객체 생성
            Thread gugu = new Thread(gu, "GUGU");
    
            // Thread 상속 클래스 객체 생성
            PrintThread pt = new PrintThread();
    
            // 스레드별 우선순위 설정
            gugu.setPriority(1);
            pt.setPriority(Thread.MAX_PRIORITY);
    
            // 스레드 실행
            gugu.start(); pt.start();
    
            /*
            5X1= 5
            727
            5X2= 10
            i: 1
            36
            i: 2
            985
            5X3= 15
            ...
            */
        }
    
    }

    ※ 두 스레드는 서로 경쟁적으로 실행되기 때문에 결과가 섞여서 출력됨
    우선순위는 pt 스레드가 더 높지만 먼저 끝나는 스레드를 확정할 수는 없음


    두 가지의 스레드 생성 방법과 멀티 스레드에 대해 알아보았습니다.

    스레드는 Thread 클래스를 상속해서 생성하는 것이 가장 좋은 방법이지만,

    다른 클래스를 상속받아야 하는 경우 Runnable 인터페이스를 구현함으로써 생성할 수도 있습니다.

    Runnable 인터페이스를 구현하는 경우에도 다시 Thread 클래스의 생성자를 이용해서 스레드 객체로 생성해야
    Thread 클래스의 다양한 메소드를 사용할 수 있기 때문에 결국에는 Thread 클래스를 이용해야 하겠습니다.

     

    멀티 스레드 이용시 여러 작업을 동시에 수행할 수 있다는 이점이 있지만

    반드시 실행 순서에 따라 작업이 완료되는 것이 아니라는 점과

    각 스레드가 충돌할 가능성이 있다는 점을 기억해야 할 것 같습니다.

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

    Java | I/O RandomAccessFile  (0) 2020.02.11
    Java | Thread (3) Synchronization 동기화  (1) 2020.02.11
    Java | Thread (1) 개요  (0) 2020.02.10
    Java | Generic (2) <?> & <T extends Class> & <? super Class>  (0) 2020.02.10
    Java | Generic (1) <T>  (0) 2020.02.10

    댓글

Designed by Tistory.