자바 스레드 생성 방식: Thread 클래스 상속과 Runnable 인터페이스 구현 비교

자바에서 새로운 스레드를 생성하고 실행하는 가장 기본적이고 널리 사용되는 두 가지 접근 방식은 Thread 클래스를 상속하는 방법과 Runnable 인터페이스를 구현하는 방법입니다. 각 방식의 구현 세부 사항과 코드 구조를 살펴보겠습니다.

1. Thread 클래스 상속

Thread 클래스를 직접 상속하여 스레드를 생성하는 방식은 직관적입니다. 사용자 정의 클래스가 Thread를 상속받고, 스레드가 수행할 작업 로직을 run() 메서드에 오버라이딩합니다. 스레드를 실행하려면 반드시 start() 메서드를 호출해야 하며, 이는 내부적으로 새로운 실행 흐름을 만든 후 run() 메서드를 호출합니다.

public class CustomWorker extends Thread {
    
    public CustomWorker(String workerName) {
        super(workerName);
    }

    @Override
    public void run() {
        System.out.printf("[%s] 작업 스레드가 실행 중입니다.%n", Thread.currentThread().getName());
    }
}

위에서 정의한 스레드 클래스를 인스턴스화하고 실행하는 코드는 다음과 같습니다.

public class ThreadInheritanceExample {
    public static void main(String[] args) {
        CustomWorker worker = new CustomWorker("Alpha-Worker");
        worker.start();
        
        System.out.printf("[%s] 메인 스레드 실행 완료.%n", Thread.currentThread().getName());
    }
}

또한, 별도의 클래스 파일을 생성하지 않고 익명 내부 클래스(Anonymous Inner Class)를 활용하여 즉석에서 Thread를 확장하고 실행할 수도 있습니다.

public class AnonymousThreadExample {
    public static void main(String[] args) {
        Thread inlineWorker = new Thread("Beta-Worker") {
            @Override
            public void run() {
                System.out.printf("[%s] 익명 스레드가 실행 중입니다.%n", Thread.currentThread().getName());
            }
        };
        inlineWorker.start();
    }
}

2. Runnable 인터페이스 구현

자바는 다중 상속을 지원하지 않으므로, 이미 다른 클래스를 상속받고 있는 경우 Thread 클래스를 상속할 수 없습니다. 이때 Runnable 인터페이스를 구현하는 방식이 유용합니다. Runnable 구현체를 생성한 후, 이를 Thread 객체의 생성자 인자로 전달하여 스레드를 생성하고 start() 메서드를 호출합니다. 자바 8부터 도입된 람다 표현식을 사용하면 코드를 훨씬 간결하게 작성할 수 있습니다.

public class RunnableImplementationExample {
    public static void main(String[] args) {
        
        // 1. 익명 내부 클래스를 사용한 Runnable 구현
        Runnable legacyTask = new Runnable() {
            @Override
            public void run() {
                System.out.printf("[%s] 레거시 방식의 작업이 실행 중입니다.%n", Thread.currentThread().getName());
            }
        };
        Thread threadA = new Thread(legacyTask, "Task-Thread-A");
        threadA.start();

        // 2. 람다 표현식을 사용한 Runnable 구현
        Runnable modernTask = () -> {
            System.out.printf("[%s] 모던 방식의 작업이 실행 중입니다.%n", Thread.currentThread().getName());
        };
        Thread threadB = new Thread(modernTask, "Task-Thread-B");
        threadB.start();

        System.out.printf("[%s] 메인 메서드 종료.%n", Thread.currentThread().getName());
    }
}

태그: java Multithreading Thread Runnable LambdaExpressions

9월 10일 11:52에 게시됨