본문 바로가기

개발/Java

Java의 스레드와 콜스택

 

🧵 자바 스레드와 콜스택 완벽 정리


✅ 자바에서 스레드를 만드는 두 가지 방법

자바에서 멀티스레드를 구현하는 방법은 대표적으로 두 가지가 있다:

1. Thread 클래스 상속

class MyThread extends Thread {
    public void run() {
        System.out.println("스레드 실행 중");
    }
}
  • Thread 클래스 자체를 상속하고 run() 메서드를 오버라이딩한다
  • 단점: 자바는 단일 상속만 가능하기 때문에, 다른 클래스를 동시에 상속받을 수 없다

2. Runnable 인터페이스 구현

class MyRunnable implements Runnable {
    public void run() {
        System.out.println("Runnable 실행 중");
    }
}

// 실행
Thread t = new Thread(new MyRunnable());
t.start();
  • Runnable은 실행 로직만 정의하고, Thread 클래스에 위임하여 실행함
  • 훨씬 유연하고 실무에서 훨씬 많이 사용됨

✅ start()와 run()의 차이

메서드 의미 실행 결과

run() 그냥 메서드 호출 새로운 스레드 없이 현재 스레드에서 실행
start() JVM에게 새 스레드를 만들라고 요청 진짜로 새로운 스레드가 생성

예시

Runnable r = new MyRunnable();
r.run();      // ❌ main 스레드에서 실행됨 (멀티스레드 아님)

Thread t = new Thread(r);
t.start();    // ✅ 별도의 스레드가 생성됨

start()는 "감독이 액션!"을 외쳐 새로운 배우(스레드)가 등장하는 것이고,
run()은 대본만 혼자 읽는 느낌이다 (멀티스레드 아님).


✅ Runnable에는 왜 start()가 없을까?

Runnable은 단순히 "할 일(run())을 정의한 인터페이스"일 뿐, 스레드 기능은 없다.
실제로 스레드를 생성하려면 Thread 클래스의 start() 메서드를 사용해야 하므로, 아래처럼 작성해야 한다:

Runnable task = new MyRunnable();
Thread t = new Thread(task);
t.start(); // 이걸로만 진짜 스레드 실행 가능!

✅ run()은 콜스택과 무슨 관계가 있을까?

run()도 일반적인 메서드이기 때문에 호출되면 콜스택에 올라간다.
하지만 스레드마다 콜스택을 따로 하나씩 가지기 때문에 실행 방식에 따라 콜스택 구조가 달라진다.

run() 직접 호출 시

  • 같은 스레드(main) 안에서 실행됨
  • 콜스택: main() → run() (같은 스택)

start()로 실행 시

  • JVM이 새로운 스레드와 새로운 콜스택을 만들어줌
  • 콜스택1: main()
  • 콜스택2: run() (새로운 스레드에서)

✅ 스레드당 콜스택은 하나

모든 자바 스레드는 고유한 콜스택 하나만을 가지고 있다.
콜스택은 스레드가 실행 중 호출하는 모든 메서드를 추적하고 관리하는 공간이다.

예를 들어 다음과 같이 여러 스레드를 만들면:

public static void main(String[] args) {
    new Thread(() -> sayHello()).start();
    new Thread(() -> sayBye()).start();
}
  • main()은 main 스레드의 콜스택에서 실행
  • sayHello()는 Thread-0의 콜스택에서 실행
  • sayBye()는 Thread-1의 콜스택에서 실행

스레드가 많아질수록 각각 독립적인 콜스택을 가지고 동작하게 된다.


💬 마무리 요약

  • 자바에서 스레드는 Thread 상속 또는 Runnable 구현으로 만들 수 있다
  • 실행은 반드시 start()로 해야 새로운 스레드에서 run()이 동작한다
  • run()만 호출하면 현재 스레드에서 그냥 메서드처럼 실행될 뿐이다
  • 모든 스레드는 자신의 콜스택 하나를 가지고 있으며, 메서드 실행 흐름은 그 스택 안에서 관리된다

 

'개발 > Java' 카테고리의 다른 글

Java 버전에 따른 GC  (0) 2025.05.27
불변 객체(immutable object)의 개념과 사용  (0) 2025.05.24
직렬화  (0) 2025.05.22
원시타입(Primitive type)과 참조타입(Reference type)  (0) 2025.05.22
Java GC(Garbage Collector)  (1) 2024.12.04