본문 바로가기

Java

Thread 구현과 실행 (Runnable vs Thread)

728x90

이번 포스팅은 Thread를 구현하는 방법 2가지Thread의 start()와 run() 메서드의 차이점에 대하여 포스팅해 보았습니다.


 Thread 생성

1. Thread 클래스 상속

선언


class Thread_1 extends Thread{
    @Override
    public void run(){
        for(int i=0;i<5;++i){
            System.out.println(i);
        }
    }
}

 

사용


Thread_1 thread_1 = new Thread_1();
thread_1.start(); // 한 번만 실행 가능

만약 start()를 여러 번 사용하고 싶다면 사용할 때마다 새로운 객체를 생성해야 합니다.

 


2. Runnable 인터페이스 상속

선언


class Thread_2 implements Runnable {
    @Override
    public void run() {
        for (int i = 6; i < 10; ++i) {
            System.out.println(i);
        }
    }
}

 

사용


Runnable r = new Thread_2();
Thread thread_2 = new Thread(r);
thread_2.run();

자바는 다중 상속이 불가하기 때문에 보통 Thread 클래스를 상속받아서 thread를 구현하기보다는 Runnable 인터페이스를 이용하는 경우가 많습니다.


전체코드

public class Main {
    public static void main(String[] args) {
        Thread_1 thread_1 = new Thread_1();
        thread_1.start();

        Runnable r = new Thread_2();
        Thread thread_2 = new Thread(r);
        thread_2.start();
    }
}

class Thread_1 extends Thread {
    @Override
    public void run() {
        System.out.println(getName()); // Thread 클래스의 메서드 직접 호출 가능
        for (int i = 0; i < 5; ++i) {
            System.out.println(i);
        }
    }
}

class Thread_2 implements Runnable {

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()); // Thread 클래스의 static메서드인 currentThread()로 
       	                                                     //쓰레드에 대한 참조를 얻어야 메서드 호출 가능
        for (int i = 6; i < 10; ++i) {
            System.out.println(i);
        }
    }
}

 

[결과]

Thread-0
0
1
2
3
4
Thread-1
5
6
7
8
9

 


start() vs run()

위의 코드를 작성하다가 저도 모르게 thread_2.start() 대신 thread_2.run()으로 작성하였더니 출력 결과가 Thread-1이 아니라 main이라고 나와서 당황스러웠습니다. start()와 run()의 차이가 무엇인지 궁금해서 찾아보았더니 아래와 같이 차이점이 있다고 합니다.

 

start()

새로운 쓰레드가 작업을 실행하는데 필요한 호출스택을 새로 생성한 다음에, run()을 호출해서 생성된 호출스택에 run()이 첫 번째로 올라가게  합니다. 즉 아래와 같이 스택이 생성된 후, run()이 호출되고, 그 후 start() 메서드는 사라진 채로 동작하게 됩니다.


Phase 1
Phase 2


run()

생성된 쓰레드를 실행시키는 것이 아닌, 단순히 클래스에 선언된 메서드를 호출하는 것입니다. 따라서 새로운 호출스택을 생성하는 것이 아니라 이미 실행되고 있는 main의 호출스택 위에 run()이 두 번째로 올라가게 되는 것입니다.


 

 

728x90
반응형

'Java' 카테고리의 다른 글

Thread 실행 제어  (0) 2023.10.27
제네릭(Generic)이란?  (0) 2023.10.25
자바의 애너테이션(Annotation)  (2) 2023.10.22
자바에서 애너테이션(Annotation) 직접 정의하기  (0) 2023.10.22
-Xlint 옵션  (0) 2023.10.21