|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: "[JAVA] 스레드 생성과 실행" |
| 4 | +date: 2025-10-27 |
| 5 | +category: JAVA |
| 6 | +--- |
| 7 | + |
| 8 | +## 자바 메모리 구조 |
| 9 | + |
| 10 | +자바 메모리 구조는 총 메서드 영역, 스택 영역, 힙 영역 이렇게 3가지 영역으로 구성되어 있다. |
| 11 | + |
| 12 | + |
| 13 | + |
| 14 | +- 메서드 영역: 프로그램 공통 데이터 관리 |
| 15 | + - 클래스 정보: 클래스의 실행 코드(바이트 코드), 필드, 메서드, 생성자 코드 등 모든 실행코드 |
| 16 | + - static 영역: `static` 변수 보관 |
| 17 | + - 런타임 상수 풀: 공통 리터럴 상수 보관 |
| 18 | + |
| 19 | + |
| 20 | +- 스택 영역: 스레드별 하나의 실행 스택이 생성됨 |
| 21 | + - 스택 프레임: 메서드를 호출할 때마다 하나의 스택 프레임이 쌓이고, 종료되면 해당 스택 프레임이 제거됨 |
| 22 | + - 각 스택 프레임은 `메서드를 실행하기 위한 정보` (지역 변수, 중간 연산 결과, 메서드 호출 정보 등)를 포함 |
| 23 | + |
| 24 | + |
| 25 | +- 힙 영역: 객체(인스턴스)와 배열이 생성되는 영역 |
| 26 | + - 가비지 컬렉션(GC)이 이루어지는 주요 영역이며, 더 이상 참조되지 않는 객체는 GC에 의해 제거됨 |
| 27 | + |
| 28 | +## 스레드 생성 방법 1.Thread 클래스 상속 |
| 29 | + |
| 30 | +자바는 많은 것을 객체로 다룬다. 예외를 객체로 다루듯이, 스레드도 객체로 다룬다. |
| 31 | +스레드가 필요하면, 스레드 객체를 생성해서 사용하면 된다. |
| 32 | + |
| 33 | +```java |
| 34 | +package thread.start; |
| 35 | + |
| 36 | +public class HelloThread extends Thread { |
| 37 | + |
| 38 | + @Override |
| 39 | + public void run() { |
| 40 | + System.out.println(Thread.currentThread().getName() + ": run()"); |
| 41 | + } |
| 42 | +} |
| 43 | + |
| 44 | +``` |
| 45 | + |
| 46 | +- `Thread` 클래스를 상송하고, 스레드가 실행할 코드를 `run()` 메서드에 재정의한다 |
| 47 | + |
| 48 | +```java |
| 49 | +package thread.start; |
| 50 | + |
| 51 | +public class HelloRunnableMain { |
| 52 | + |
| 53 | + public static void main(String[] args) { |
| 54 | + System.out.println(Thread.currentThread().getName() + ": main() start"); |
| 55 | + |
| 56 | + HelloRunnable runnable = new HelloRunnable(); |
| 57 | + Thread thread = new Thread(runnable); |
| 58 | + thread.start(); |
| 59 | + |
| 60 | + System.out.println(Thread.currentThread().getName() + ": main() end"); |
| 61 | + } |
| 62 | +} |
| 63 | + |
| 64 | +``` |
| 65 | + |
| 66 | +- 앞서 만든 `HelloThread` 스레드 객체를 생성하고 `start()` 메서드를 호출한다 |
| 67 | +- `start()` 매서드는 스레드를 실행하는 아주 특별한 메서드이다 |
| 68 | +- `start()` 를 호출하면 `HelloThread` 스레드가 `run()` 매서드를 실행한다 |
| 69 | +- `run()` 메서드가 아니라 반드시 `start()` 메서드를 호출해야한다. 그래야 별도의 스레드에서 `run()` 코드가 실행된다 |
| 70 | + |
| 71 | +### 스레드 생성 후 메모리 분석 |
| 72 | + |
| 73 | + |
| 74 | + |
| 75 | +### 시간의 흐름으로 분석 |
| 76 | + |
| 77 | + |
| 78 | + |
| 79 | +- 여기서 핵심은 `main` 스레드가 `run()` 메서드를 실행하는게 아니라 `Thread-0` 스레드가 `run()` 메서드를 실행한다는 점이다. |
| 80 | +- `main` 스레드는 단지 `start()` 메서드를 통해 `Thread-0` 스레드에게 실행을 지시할 뿐이다. |
| 81 | +- `main` 스레드가 `run()` 을 호출하는 것이 아니다! `main` 스레드는 다른 스레드에게 일을 시작하라고 지시만 하고, 바로 `start()` 메서드를 빠져나온다. |
| 82 | +- **스레드 간 실행 순서는 보장하지 않는다.** |
| 83 | + 스레드는 동시에 실행되기 때문에 스레드 간에 실행 순서는 얼마든지 달라질 수 있다. |
| 84 | +## 스레드 생성 방법 2. Runnable 인터페이스 구현 |
| 85 | + |
| 86 | +```java |
| 87 | +package thread.start; |
| 88 | + |
| 89 | +public class HelloRunnable implements Runnable { |
| 90 | + |
| 91 | + @Override |
| 92 | + public void run() { |
| 93 | + System.out.println(Thread.currentThread().getName() + ": run()"); |
| 94 | + } |
| 95 | +} |
| 96 | + |
| 97 | +``` |
| 98 | + |
| 99 | +```java |
| 100 | +package thread.start; |
| 101 | + |
| 102 | +public class HelloRunnableMain { |
| 103 | + |
| 104 | + public static void main(String[] args) { |
| 105 | + System.out.println(Thread.currentThread().getName() + ": main() start"); |
| 106 | + |
| 107 | + HelloRunnable runnable = new HelloRunnable(); |
| 108 | + Thread thread = new Thread(runnable); |
| 109 | + thread.start(); |
| 110 | + |
| 111 | + System.out.println(Thread.currentThread().getName() + ": main() end"); |
| 112 | + } |
| 113 | +} |
| 114 | + |
| 115 | +``` |
| 116 | +- 이전에 Thread 객체를 생성했을 때와 결과의 차이는 없다 |
| 117 | +- 차이가 있다면, 스레드와 해당 스레드가 실행할 작업이 서로 분리되어 있다는 점이다 |
| 118 | +- 스레드 객체를 생성할 때, 실행할 작업을 생성자로 전달하면 된다 |
| 119 | + |
| 120 | +### Runnable 인터페이스 구현 방식의 장점 |
| 121 | +- 상속의 자유로움: `Runnable` 인터페이스 방식은 다른 클래스를 상속받아도 문제없이 구현할 수 있다 (Thread를 상속받은 경우 다중 상속은 불가함) |
| 122 | +- 코드의 분리: 스레드와 실행할 작업을 분리하여 코드의 가독성을 높일 수 있다 |
| 123 | +- 여러 스레드가 동일한 `Runnable` 객체를 공유할 수 있어 자원 관리를 효율적으로 할 수 있다 |
| 124 | + |
| 125 | +위와 같은 이유들로 스레드를 생성하고 사용할 때 Runnable 인터페이스 구현 방식이 권장된다. |
| 126 | + |
| 127 | +### 참고 자료 |
| 128 | + |
| 129 | +- [김영한의 실전 자바 - 고급 1편, 멀티스레와 동시성](https://www.inflearn.com/course/%EA%B9%80%EC%98%81%ED%95%9C%EC%9D%98-%EC%8B%A4%EC%A0%84-%EC%9E%90%EB%B0%94-%EA%B3%A0%EA%B8%89-1/) |
| 130 | +- [코드 구현](https://github.com/chjung99/java-adv1.git) |
0 commit comments