관리 메뉴

Unfazedβ—οΈπŸŽ―

[Java] μŠ€λ ˆλ“œ 생성 λ©”μ»€λ‹ˆμ¦˜κ³Ό JVM의 μŠ€λ ˆλ“œ 관리 λ°©μ‹μœΌλ‘œ μ΄ν•΄ν•˜λŠ” μŠ€λ ˆλ“œ start(), run() λ©”μ„œλ“œμ˜ 차이 λ³Έλ¬Έ

Java

[Java] μŠ€λ ˆλ“œ 생성 λ©”μ»€λ‹ˆμ¦˜κ³Ό JVM의 μŠ€λ ˆλ“œ 관리 λ°©μ‹μœΌλ‘œ μ΄ν•΄ν•˜λŠ” μŠ€λ ˆλ“œ start(), run() λ©”μ„œλ“œμ˜ 차이

9taetae9 2025. 2. 7. 15:29
728x90

Javaμ—μ„œ start() λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•΄μ•Ό ν•˜λŠ” μ΄μœ μ™€ run() λ©”μ„œλ“œ 직접 호좜의 λ¬Έμ œμ μ„ μ•Œμ•„λ³΄μž.

 

1. μŠ€λ ˆλ“œ μ‹€ν–‰ λ©”μ»€λ‹ˆμ¦˜μ˜ 핡심 차이

start() λ©”μ„œλ“œμ˜ μ—­ν• 

μƒˆλ‘œμš΄ 호좜 μŠ€νƒ(Call Stack)을 μƒμ„±ν•˜μ—¬ JVM이 ν•΄λ‹Ή μŠ€λ ˆλ“œλ₯Ό μŠ€μΌ€μ€„λ§ν•  수 μžˆλ„λ‘ μ€€λΉ„ μƒνƒœλ‘œ μ „ν™˜ν•œλ‹€. 이 κ³Όμ •μ—μ„œ λ„€μ΄ν‹°λΈŒ λ©”μ„œλ“œ start0()κ°€ 호좜되며, μ΄λŠ” OS μˆ˜μ€€μ—μ„œ μ‹€μ œ μŠ€λ ˆλ“œ λ¦¬μ†ŒμŠ€λ₯Ό ν• λ‹Ήν•˜λŠ” 역할을 μˆ˜ν–‰ν•œλ‹€.

 

run() 직접 호좜의 문제점

ν˜„μž¬ μ‹€ν–‰ 쀑인 μŠ€λ ˆλ“œμ˜ 호좜 μŠ€νƒμ—μ„œ λ™κΈ°μ μœΌλ‘œ μ½”λ“œκ°€ μ‹€ν–‰λœλ‹€. μ΄λŠ” λ‹¨μˆœ λ©”μ„œλ“œ 호좜과 λ™μΌν•œ λ°©μ‹μœΌλ‘œ μž‘λ™ν•˜λ©°, λ©€ν‹°μŠ€λ ˆλ”©μ˜ 핡심인 병렬 싀행이 λ˜μ§€ μ•ŠλŠ”λ‹€.

// 잘λͺ»λœ μ‚¬μš© μ˜ˆμ‹œ
Thread myThread = new MyCustomThread();
myThread.run();  // 메인 μŠ€λ ˆλ“œμ—μ„œ 순차 μ‹€ν–‰

 

2. μŠ€λ ˆλ“œ 관리

μƒνƒœ 전이 start()호좜 μ‹œ run()직접 호좜 μ‹œ
NEW RUNNABLE O (μŠ€λ ˆλ“œ 풀에 등둝) X (μƒνƒœ λ³€ν™” μ—†μŒ)
독립적 μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ O (μƒˆ μŠ€νƒ λ©”λͺ¨λ¦¬ ν• λ‹Ή) X (κΈ°μ‘΄ μŠ€νƒ μ‚¬μš©)
GC 관리 λŒ€μƒ O (μ‹€ν–‰ μ’…λ£Œ ν›„ μžλ™ ν•΄μ œ) X (λͺ…μ‹œμ  ν•΄μ œ ν•„μš”)

 

JVM의 μŠ€λ ˆλ“œ μŠ€μΌ€μ€„λŸ¬λŠ” start()λ₯Ό 톡해 λ“±λ‘λœ μŠ€λ ˆλ“œλ§Œμ„ 관리 λŒ€μƒμœΌλ‘œ μ‚ΌλŠ”λ‹€. run() 직접 호좜 μ‹œ μŠ€λ ˆλ“œ κ°μ²΄λŠ” 일반 μžλ°” 객체와 λ™μΌν•˜κ²Œ μ·¨κΈ‰λœλ‹€.

 

3. 병렬성 ν…ŒμŠ€νŠΈ 

start() 호좜 μ‹œ

public class Main {
    public static class ConcurrencyDemo {
        public static void main(String[] args) {
            Thread t1 = new TaskThread("T1");
            Thread t2 = new TaskThread("T2");

            t1.start();  // 병렬 μ‹€ν–‰
            t2.start();
        }
    }
    static class TaskThread extends Thread {
        public TaskThread(String name) {
            this.setName(name);
        }

        public void run() {
            IntStream.range(0, 5).forEach(i -> {
                System.out.println(Thread.currentThread().getName() + " - " + i);
            });
        }
    }
}

start() 호좜 결과

μœ„μ˜ μ½”λ“œμ™€ μ‹€ν–‰ 결과와 같이 μŠ€λ ˆλ“œ T1, T2의 좜λ ₯ μˆœμ„œκ°€ λ§€ μ‹€ν–‰λ§ˆλ‹€ λ‹¬λΌμ§€λŠ” 것이 정상적인 병렬 μ‹€ν–‰μ˜ 결과라 ν•  수 μžˆλ‹€.

 

run() 호좜 μ‹œ

κ·Έλ ‡λ‹€λ©΄ run()을 직접 호좜 μ‹œ κ²°κ³ΌλŠ” μ–΄λ–¨κΉŒ?

μœ„ μ½”λ“œμ—μ„œ start() 호좜 라인만 run()으둜 λ³€κ²½ν•œλ’€ μ‹€ν–‰ν•΄λ³΄μž.

public static void main(String[] args) {
    Thread t1 = new TaskThread("T1");
    Thread t2 = new TaskThread("T2");

    t1.run();  // 병렬 μ‹€ν–‰ X
    t2.run();
}

run() 호좜 결과

 

μ‹€ν–‰ κ²°κ³Όμ—μ„œ λ³Ό 수 μžˆλ“―μ΄ λͺ¨λ“  좜λ ₯이 순차적으둜 λ°œμƒν•œλ‹€. 즉, t1에 λŒ€ν•œ run() λ‘œμ§μ„ λͺ¨λ‘ μ‹€ν–‰ν•œ 뒀에야 t2κ°€ μž‘μ—…μ„ μ²˜λ¦¬ν•œλ‹€.

μ°¨μ΄λŠ” 이뿐만이 μ•„λ‹ˆλ‹€.

μœ„μ˜ start() 호좜 κ²°κ³Όμ—μ„œ 싀행쀑인 μŠ€λ ˆλ“œκ°€ T1, T2둜 좜λ ₯λ˜λŠ” 것과 달리, run()호좜 μ‹œμ—λŠ” ν˜„μž¬ μž‘μ—… 쀑인 μŠ€λ ˆλ“œκ°€ main으둜 좜λ ₯λ˜λŠ” 것을 λ³Ό 수 μžˆλ‹€.

 

μ΄λŸ¬ν•œ κ²°κ³ΌλŠ” μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ˜ 근본적 μ°¨μ΄μ—μ„œ λΉ„λ‘―λ˜λŠ”λ°, μŠ€λ ˆλ“œ 생성 λ©”μ»€λ‹ˆμ¦˜κ³Ό JVM의 μŠ€λ ˆλ“œ 관리 방식에 λŒ€ν•œ 이해가 ν•„μš”ν•˜λ‹€.

 

start() μ‚¬μš© μ‹œ

  1. JVM이 start0() λ„€μ΄ν‹°λΈŒ λ©”μ„œλ“œλ₯Ό 톡해 OS μˆ˜μ€€μ—μ„œ μƒˆ μŠ€λ ˆλ“œ 생성
  2. μƒˆ μŠ€λ ˆλ“œμ˜ 호좜 μŠ€νƒμ— run() λ©”μ„œλ“œ ν”„λ ˆμž„ 생성 //(각 μŠ€λ ˆλ“œλŠ” 독립적인 μŠ€νƒ 곡간과 Instruction Pointerλ₯Ό κ°–λŠ”λ‹€)
  3. Thread.currentThread()κ°€ μƒˆ μŠ€λ ˆλ“œ 객체 λ°˜ν™˜
// T1 μŠ€λ ˆλ“œμ˜ run() μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ
public void run() {
    System.out.println(Thread.currentThread().getName()); // "T1"
}

 

run() 직접 호좜 μ‹œ

  1. ν˜„μž¬ μŠ€λ ˆλ“œ(메인)의 호좜 μŠ€νƒμ—μ„œ 직접 μ‹€ν–‰
  2. Thread.currentThread()λŠ” 메인 μŠ€λ ˆλ“œ 객체 λ°˜ν™˜
myThread.run();  // 메인 μŠ€λ ˆλ“œ μ»¨ν…μŠ€νŠΈμ—μ„œ μ‹€ν–‰
System.out.println(Thread.currentThread().getName()); // "main"

 

정리

  1. μ‹€ν–‰ 주체의 뢄리 : start()λŠ” μƒˆλ‘œμš΄ μ‹€ν–‰ 주체(μŠ€λ ˆλ“œ)λ₯Ό μƒμ„±ν•˜μ§€λ§Œ, run() 직접 ν˜ΈμΆœμ€ κΈ°μ‘΄ μ‹€ν–‰ 주체λ₯Ό μ‚¬μš©ν•œλ‹€.
  2. μŠ€λ ˆλ“œ 식별 λ©”μ»€λ‹ˆμ¦˜ : Thread.currentThread()λŠ” 항상 ν˜„μž¬ μ½”λ“œλ₯Ό μ‹€ν–‰ 쀑인 μŠ€λ ˆλ“œλ₯Ό λ°˜ν™˜ν•œλ‹€. run()을 직접 ν˜ΈμΆœν•˜λ©΄ 호좜자의 μŠ€λ ˆλ“œ(main)κ°€ μ‹€ν–‰ 주체가 λœλ‹€.
  3. μŠ€λ ˆλ“œ 클래슀의 run() λ©”μ„œλ“œλŠ” μ‹€ν–‰ν•  μž‘μ—…μ„ μ •μ˜ν•˜λŠ” ν…œν”Œλ¦Ώμ΄λ©°, start()λŠ” μ‹€ν–‰ 주체 관리λ₯Ό μœ„ν•œ λ©”μ»€λ‹ˆμ¦˜μœΌλ‘œ μ„€κ³„λ˜μ—ˆλ‹€.
  • start(): μ‹€ν–‰ μŠ€λ ˆλ“œ 생성 + μž‘μ—… μ‹€ν–‰
  • run(): μž‘μ—… μ‹€ν–‰λ§Œ (μ‹€ν–‰ 주체 λ³€ν™” μ—†μŒ)

μΆ”κ°€ - start(), run() 호좜 방식 상세 비ꡐ

  1. start() 호좜 μ‹œ
    • μƒˆλ‘œμš΄ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ 생성: start() λ©”μ„œλ“œλŠ” λ‚΄λΆ€μ μœΌλ‘œ λ„€μ΄ν‹°λΈŒ λ©”μ„œλ“œ start0()λ₯Ό ν˜ΈμΆœν•˜μ—¬ OS에 μƒˆλ‘œμš΄ μŠ€λ ˆλ“œ 생성을 μš”μ²­ν•œλ‹€. OSλŠ” 이 μš”μ²­μ— 따라 μƒˆλ‘œμš΄ μŠ€λ ˆλ“œ μ œμ–΄ 블둝(TCB)을 μƒμ„±ν•˜κ³ , JVM은 OSκ°€ μƒμ„±ν•œ TCB와 java.lang.Thread 객체λ₯Ό λ§€ν•‘ν•œλ‹€. 
    • λ™μ‹œμ„± 및 병렬 μ‹€ν–‰: OS μŠ€μΌ€μ€„λŸ¬κ°€ μƒˆ μŠ€λ ˆλ“œλ₯Ό Runnable μƒνƒœλ‘œ μ „ν™˜ν•˜κ³ , μŠ€μΌ€μ€„λ§μ— 따라 각각 독립적인 μŠ€λ ˆλ“œ(T1, T2 λ“±)μ—μ„œ run() λ©”μ„œλ“œκ°€ μ‹€ν–‰λœλ‹€. 이둜 인해 μ—¬λŸ¬ μŠ€λ ˆλ“œκ°€ λ³‘λ ¬λ‘œ 싀행될 수 있으며, 각 μŠ€λ ˆλ“œμ˜ 이름이 좜λ ₯λ˜λŠ” 결과도 μ„œλ‘œ λ‹€λ₯΄λ‹€.
  2. run() 직접 호좜 μ‹œ
    • ν˜„μž¬ μŠ€λ ˆλ“œμ—μ„œ 순차 μ‹€ν–‰: run()을 직접 ν˜ΈμΆœν•˜λ©΄ μƒˆλ‘œμš΄ μŠ€λ ˆλ“œλ₯Ό μƒμ„±ν•˜μ§€ μ•Šκ³ , λ‹¨μˆœνžˆ 일반 λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜λŠ” 것과 λ™μΌν•˜λ‹€. λ”°λΌμ„œ run() λ‚΄ 둜직이 호좜된 μŠ€λ ˆλ“œ(보톡 main μŠ€λ ˆλ“œ)μ—μ„œ 순차적으둜 μ‹€ν–‰λ˜λ―€λ‘œ, μŠ€λ ˆλ“œ 이름도 λͺ¨λ‘ main으둜 ν‘œμ‹œλœλ‹€.
    • 병렬성 λΆ€μž¬: λ³„λ„μ˜ μŠ€λ ˆλ“œκ°€ μ—†μœΌλ―€λ‘œ λ³‘λ ¬λ‘œ μ—¬λŸ¬ μž‘μ—…μ΄ μ‹€ν–‰λ˜μ§€ μ•Šκ³ , ν•œ μž‘μ—…μ΄ λλ‚œ 후에 λ‹€μŒ μž‘μ—…μ΄ μ‹€ν–‰λœλ‹€.

 λ”°λΌμ„œ, μŠ€λ ˆλ“œλ₯Ό ν†΅ν•œ 병렬 처리 및 λ™μ‹œμ„±μ„ κ΅¬ν˜„ν•  λ•ŒλŠ” λ°˜λ“œμ‹œ start()λ₯Ό μ‚¬μš©ν•΄μ•Ό ν•œλ‹€λŠ” 점을 λͺ…μ‹¬ν•˜μž.

 

μ‹€ν–‰ μ£ΌκΈ° 관리 흐름 μš”μ•½

  1. JVM: start0() 호좜 → OS μŠ€λ ˆλ“œ 생성 μš”μ²­
  2. OS: μŠ€λ ˆλ“œ TCB(Thread Control Block) 생성 
  3. JVM: java.lang.Thread 객체와 OS μŠ€λ ˆλ“œ λ§€ν•‘
  4. OS μŠ€μΌ€μ€„λŸ¬: Runnable μƒνƒœλ‘œ μ „ν™˜
  5. JVM: run() λ©”μ„œλ“œ 호좜 μ‹œμž‘
  6. μ‹€ν–‰ μ™„λ£Œ ν›„ OS λ¦¬μ†ŒμŠ€ λ°˜ν™˜

 

μš©μ–΄ 정리

  • TCB : OSκ°€ 각 μŠ€λ ˆλ“œλ₯Ό κ΄€λ¦¬ν•˜κΈ° μœ„ν•΄ μœ μ§€ν•˜λŠ” 데이터 ꡬ쑰둜 μŠ€λ ˆλ“œμ˜ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ™€ μƒνƒœ, μŠ€νƒλ₯Ό μ €μž₯
  • μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ :  νŠΉμ • μ‹œμ μ— μŠ€λ ˆλ“œκ°€ μž‘μ—…μ„ μˆ˜ν–‰ν•˜κΈ° μœ„ν•΄ ν•„μš”ν•œ λͺ¨λ“  μƒνƒœ 정보 (OSκ°€ μŠ€λ ˆλ“œλ₯Ό μ€‘λ‹¨ν–ˆλ‹€κ°€ λ‹€μ‹œ μ‹€ν–‰ν•  λ•Œ μ •ν™•νžˆ μ€‘λ‹¨λœ 지점뢀터 μž¬κ°œν•  수 μžˆλ„λ‘ 함)
    • μŠ€λ ˆλ“œμ˜ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ 핡심 ꡬ성 μš”μ†Œ : ν”„λ‘œκ·Έλž¨ μΉ΄μš΄ν„°, μŠ€νƒ λ©”λͺ¨λ¦¬, CPU λ ˆμ§€μŠ€ν„° μƒνƒœ, μŠ€λ ˆλ“œ μƒνƒœ, μ°Έμ‘° λ¦¬μ†ŒμŠ€

 

 

참고 자료:

https://www.simplilearn.com/tutorials/java-tutorial/thread-in-java

 

Java Threads: Thread Life Cycle and Threading Basics

Learn about threads in Java, threading basics, and thread life cycle stages. Understand how Java threads enable multitasking and efficient program execution.

www.simplilearn.com

https://hello-woody.medium.com/%EB%A9%80%ED%8B%B0-%EC%8A%A4%EB%A0%88%EB%93%9C-1-%EC%9E%90%EB%B0%94%EC%97%90%EC%84%9C-%EC%8A%A4%EB%A0%88%EB%93%9C%EC%9D%98-%EC%83%9D%EC%84%B1%EA%B3%BC-%EC%8B%9C%EC%9E%91-%EA%B7%B8%EB%A6%AC%EA%B3%A0-%EC%9E%90%EB%B0%94-%EC%8A%A4%EB%A0%88%EB%93%9C%EC%99%80-os-%EC%8A%A4%EB%A0%88%EB%93%9C-%EB%A7%B5%ED%95%91-35f6cbbb8958

 

λ©€ν‹° μŠ€λ ˆλ“œβ€Š—β€Š1. μžλ°”μ—μ„œ μŠ€λ ˆλ“œμ˜ 생성과 μ‹œμž‘, 그리고 μžλ°” μŠ€λ ˆλ“œμ™€ os μŠ€λ ˆλ“œ λ§΅ν•‘

ν”„λ‘œμ„ΈμŠ€μ™€ μŠ€λ ˆλ“œ

hello-woody.medium.com

 

728x90