반응형
Thread와 Runnable 완벽 이해하기
이전 글에서:
- 프로세스(Process)
- 스레드(Thread)
의 개념을 배웠습니다.
이번에는 Java에서 실제로 스레드를 만드는 방법인:
Thread
Runnable
을 알아보겠습니다.
실무 면접에서도 정말 자주 나오는 주제입니다.
특히:
new Thread(...)
와
implements Runnable
의 차이,
그리고
run()
과
start()
의 차이는 반드시 이해해야 합니다.
대표 이미지



1. Thread란?
Thread 는
JVM 내부의 실행 흐름 단위
입니다.
2. Java 프로그램 시작 시
사실 이미 Thread가 존재합니다.
public static void main(String[] args)
이 코드를 실행하는 것도
Main Thread
입니다.
3. 확인해 보기
public class Main {
public static void main(String[] args) {
System.out.println(
Thread.currentThread().getName()
);
}
}
출력
main
4. Thread 직접 생성
가장 단순한 방법.
public class MyThread
extends Thread {
@Override
public void run() {
System.out.println("실행");
}
}
5. 실행
MyThread thread = new MyThread();
thread.start();
6. 결과
실행
7. 그런데 여기서 의문
왜
run()
을 만들었는데
실행은
start()
를 호출할까?
8. run() 역할
run()은
스레드가 실제 수행할 작업
입니다.
9. start() 역할
매우 중요.
새로운 스레드 생성 요청
입니다.
10. JVM 내부 흐름
thread.start();
↓
새 Thread 생성
↓
OS 스케줄러 등록
↓
run() 호출
11. run() 직접 호출하면?
많이 틀리는 문제.
thread.run();
12. 결과
새 Thread 생성 안 됨.
13. 실제 동작
Main Thread
↓
run() 메서드 호출
일 뿐.
14. 예시
Thread t = new Thread(
() -> {
System.out.println(
Thread.currentThread().getName()
);
}
);
t.run();
출력
main
15. start() 사용
t.start();
출력
Thread-0
16. 면접 단골
run()과 start() 차이?
run()
=
일반 메서드 호출
start()
=
새 Thread 생성 후 run() 실행
17. 그런데 Thread 상속은 문제 있음
예:
class MyThread
extends Thread
Java는
단일 상속
만 가능.
18. 문제
이미 다른 클래스 상속 중이면?
class MyService
extends BaseService
Thread 상속 불가.
19. 그래서 등장
Runnable
20. Runnable이란?
Runnable 은
실행할 작업만 정의하는 인터페이스
입니다.
21. 구조
public interface Runnable {
void run();
}
22. 구현
public class MyTask
implements Runnable {
@Override
public void run() {
System.out.println("실행");
}
}
23. 실행
Runnable task =
new MyTask();
Thread thread =
new Thread(task);
thread.start();
24. 실행 흐름
Thread
↓
Runnable.run()
25. 왜 분리했을까?
매우 중요.
26. 역할 분리
Thread
실행 주체
Runnable
실행할 작업
27. 객체지향적으로 더 좋음
작업
↓
실행
분리.
28. 실무는 Runnable 중심
대부분:
new Thread(...)
직접 잘 안 씀.
29. 예시
Runnable task =
() -> {
System.out.println(
Thread.currentThread()
.getName()
);
};
30. Lambda 사용
Runnable은
@FunctionalInterface
라서
람다 가능.
31. 실무 스타일
Thread thread =
new Thread(
() -> {
System.out.println("작업");
}
);
32. Thread 생성 비용
매우 중요.
Thread 하나 생성 시
OS 레벨에서:
Stack 생성
TCB 생성
스케줄링 등록
발생.
33. 그래서 문제
for(int i=0;i<100000;i++)
↓
new Thread(...)
절대 하면 안 됨.
34. 그래서 등장
나중에 배울
ExecutorService
35. Thread 상태
대표 상태:
NEW
RUNNABLE
BLOCKED
WAITING
TIMED_WAITING
TERMINATED
36. 생성 직후
Thread t =
new Thread(...);
↓
NEW
37. start()
t.start();
↓
RUNNABLE
38. 종료
run() 끝
↓
TERMINATED
39. Thread.currentThread()
매우 자주 사용.
예:
Thread.currentThread()
의미
현재 실행 중인 Thread
40. 예시
System.out.println(
Thread.currentThread()
.getName()
);
출력
main
Thread-0
pool-1-thread-1
등.
41. 실무에서 Runnable 쓰는 이유
대표 이유:
상속 제한 없음
재사용 가능
ThreadPool 연계
ExecutorService 사용 가능
42. Thread vs Runnable 비교
항목ThreadRunnable
| 형태 | 클래스 | 인터페이스 |
| 상속 필요 | O | X |
| 다중 구현 가능 | X | O |
| 실무 사용 | 적음 | 많음 |
| ExecutorService 사용 | 간접 | 직접 |
43. 실무 관점
현재는 사실
new Thread(...)
보다
ExecutorService
사용이 압도적으로 많음.
즉
Thread
↓
Runnable
↓
ExecutorService
순으로 발전.
44. 면접 단골 질문
Q. Thread와 Runnable 차이는?
Thread
=
실행 주체
Runnable
=
실행할 작업
Q. run()과 start() 차이는?
run()
=
일반 메서드 호출
start()
=
새 Thread 생성
Q. 실무에서는 어떤 걸 더 많이 쓰나요?
Runnable
+
ExecutorService
Q. Thread를 상속하는 방식이 잘 안 쓰이는 이유는?
단일 상속 제한
역할 분리 어려움
45. 핵심 흐름 요약
Runnable
↓
Thread 생성
↓
start()
↓
OS 스케줄러 등록
↓
run() 실행
46. 가장 중요한 핵심 한 줄
Thread는 실행 주체이고,
Runnable은 실행할 작업이며,
실무에서는 Runnable을 Thread 또는 ExecutorService에 전달하는 방식이 가장 많이 사용된다.
다음 글은
synchronized 원리
입니다.
여기서부터 진짜 멀티스레드 문제가 시작됩니다.
- Race Condition
- Critical Section
- Monitor Lock
- Object Header
- Biased Lock
- Lightweight Lock
- Heavyweight Lock
까지 JVM 내부 구조와 함께 연결됩니다.
반응형
'language > java' 카테고리의 다른 글
| volatile 키워드 완벽 이해하기 (0) | 2026.05.29 |
|---|---|
| synchronized 원리 완벽 이해하기 (0) | 2026.05.29 |
| 프로세스(Process) vs 스레드(Thread) 완벽 이해하기 (0) | 2026.05.29 |
| Spring MVC 예외 처리 전체 흐름 완벽 이해하기 (0) | 2026.05.29 |
| Spring @ControllerAdvice / @RestControllerAdvice 완벽 이해하기 (0) | 2026.05.29 |
댓글