Java

Thread 구현과 실행 (Runnable vs Thread)

작은별._. 2023. 10. 25. 21:02
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
반응형