πŸ“Œ Java μŠ€λ ˆλ“œ(Thread) κ°œλ… 및 ν™œμš©

My Pale Blue DotΒ·2025λ…„ 3μ›” 18일
0

JAVA

λͺ©λ‘ 보기
24/35
post-thumbnail

πŸ“… μž‘μ„±μΌ: 2025-03-18

πŸ“ 1. μŠ€λ ˆλ“œ(Thread)λž€?

μŠ€λ ˆλ“œ(Thread)λž€ ν•˜λ‚˜μ˜ ν”„λ‘œκ·Έλž¨μ—μ„œ μ‹€ν–‰λ˜λŠ” 독립적인 μ‹€ν–‰ 흐름(μž‘μ—… λ‹¨μœ„)이닀.
μžλ°”μ—μ„œ μŠ€λ ˆλ“œλ₯Ό μ‚¬μš©ν•˜λ©΄ μ—¬λŸ¬ μž‘μ—…μ„ λ™μ‹œμ— μ‹€ν–‰(병렬 처리, λ©€ν‹°νƒœμŠ€ν‚Ή) ν•  수 μžˆλ‹€.


βœ… 2. Javaμ—μ„œ μŠ€λ ˆλ“œλ₯Ό μƒμ„±ν•˜λŠ” 방법

πŸ”Ή (1) Thread 클래슀λ₯Ό μƒμ†ν•˜λŠ” 방법

class MyThread extends Thread {
    @Override
    public void run() {
        for (int i = 1; i <= 5; i++) {
            System.out.println(Thread.currentThread().getName() + " μ‹€ν–‰ 쀑: " + i);
            try {
                Thread.sleep(500); // 0.5초 λŒ€κΈ°
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

public class ThreadExample {
    public static void main(String[] args) {
        MyThread t1 = new MyThread();
        MyThread t2 = new MyThread();
        
        t1.start(); // μŠ€λ ˆλ“œ μ‹œμž‘
        t2.start();
    }
}

πŸ“Œ start()λ₯Ό ν˜ΈμΆœν•˜λ©΄ μƒˆλ‘œμš΄ μŠ€λ ˆλ“œκ°€ μƒμ„±λ˜λ©° run()이 싀행됨
πŸ“Œ Thread.sleep(500)을 μ‚¬μš©ν•˜λ©΄ 0.5초 λ™μ•ˆ μŠ€λ ˆλ“œκ°€ 멈좀


πŸ”Ή (2) Runnable μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•˜λŠ” 방법

class MyRunnable implements Runnable {
    @Override
    public void run() {
        for (int i = 1; i <= 5; i++) {
            System.out.println(Thread.currentThread().getName() + " μ‹€ν–‰ 쀑: " + i);
        }
    }
}

public class RunnableExample {
    public static void main(String[] args) {
        Thread t1 = new Thread(new MyRunnable());
        Thread t2 = new Thread(new MyRunnable());

        t1.start();
        t2.start();
    }
}

πŸ“Œ Runnable을 μ‚¬μš©ν•˜λ©΄ Threadλ₯Ό 상속받지 μ•Šμ•„λ„ μŠ€λ ˆλ“œλ₯Ό μ‹€ν–‰ν•  수 있음
πŸ“Œ Threadλ₯Ό μƒμ†ν•˜λŠ” 방법보닀 더 μœ μ—°ν•˜κ²Œ ν™œμš© κ°€λŠ₯ (닀쀑 상속 문제 ν•΄κ²°)


πŸ”Ή (3) λžŒλ‹€μ‹(Lambda) μ‚¬μš©

public class LambdaThreadExample {
    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            for (int i = 1; i <= 5; i++) {
                System.out.println(Thread.currentThread().getName() + " μ‹€ν–‰ 쀑: " + i);
            }
        });

        t1.start();
    }
}

πŸ“Œ Runnable을 λžŒλ‹€μ‹μœΌλ‘œ κ°„λ‹¨ν•˜κ²Œ ν‘œν˜„ κ°€λŠ₯
πŸ“Œ μ½”λ“œκ°€ κ°„κ²°ν•΄μ§€κ³  가독성이 쒋아짐


βœ… 3. μŠ€λ ˆλ“œμ˜ μ£Όμš” λ©”μ„œλ“œ

λ©”μ„œλ“œμ„€λͺ…
start()μƒˆλ‘œμš΄ μŠ€λ ˆλ“œλ₯Ό μ‹œμž‘
run()μŠ€λ ˆλ“œκ°€ μ‹€ν–‰ν•  μ½”λ“œ
sleep(ms)μ§€μ •λœ μ‹œκ°„(ms) λ™μ•ˆ ν˜„μž¬ μŠ€λ ˆλ“œλ₯Ό 멈좀
join()λ‹€λ₯Έ μŠ€λ ˆλ“œκ°€ μ’…λ£Œλ  λ•ŒκΉŒμ§€ ν˜„μž¬ μŠ€λ ˆλ“œκ°€ κΈ°λ‹€λ¦Ό
isAlive()μŠ€λ ˆλ“œκ°€ μ‹€ν–‰ 쀑인지 확인
setPriority(int)μŠ€λ ˆλ“œμ˜ μš°μ„ μˆœμœ„λ₯Ό μ„€μ •

β–Ά (1) sleep() 예제

class SleepThread extends Thread {
    @Override
    public void run() {
        for (int i = 1; i <= 5; i++) {
            System.out.println(Thread.currentThread().getName() + " μ‹€ν–‰ 쀑: " + i);
            try {
                Thread.sleep(1000); // 1초 λ™μ•ˆ 멈좀
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

β–Ά (2) join() 예제 (μŠ€λ ˆλ“œ μ’…λ£Œ λŒ€κΈ°)

public class JoinExample {
    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            for (int i = 1; i <= 5; i++) {
                System.out.println("T1 μ‹€ν–‰ 쀑: " + i);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        t1.start();
        
        try {
            t1.join(); // t1이 μ’…λ£Œλ  λ•ŒκΉŒμ§€ κΈ°λ‹€λ¦Ό
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("메인 μŠ€λ ˆλ“œ μ’…λ£Œ");
    }
}

πŸ“Œ join()을 μ‚¬μš©ν•˜λ©΄ t1이 끝날 λ•ŒκΉŒμ§€ main μŠ€λ ˆλ“œκ°€ κΈ°λ‹€λ¦Ό
πŸ“Œ join()이 μ—†μœΌλ©΄ main μŠ€λ ˆλ“œκ°€ λ¨Όμ € μ’…λ£Œλ  μˆ˜λ„ 있음


βœ… 4. λ©€ν‹°μŠ€λ ˆλ“œ 동기화 (Thread Synchronization)

λ©€ν‹°μŠ€λ ˆλ“œ ν™˜κ²½μ—μ„œλŠ” μ—¬λŸ¬ 개의 μŠ€λ ˆλ“œκ°€ λ™μ‹œμ— 곡유 μžμ›(λ³€μˆ˜, 파일, λ°μ΄ν„°λ² μ΄μŠ€)에 μ ‘κ·Όν•  수 μžˆλ‹€.
μ΄λ•Œ 경쟁 μƒνƒœ(Race Condition)κ°€ λ°œμƒν•  수 있으며, 이λ₯Ό λ°©μ§€ν•˜κΈ° μœ„ν•΄ 동기화(Synchronization)λ₯Ό μ‚¬μš©ν•œλ‹€.

β–Ά (1) 동기화(synchronized)λ₯Ό μ‚¬μš©ν•œ 예제

class Counter {
    private int count = 0;

    // λ™κΈ°ν™”λœ λ©”μ„œλ“œ (ν•œ λ²ˆμ— ν•˜λ‚˜μ˜ μŠ€λ ˆλ“œλ§Œ μ ‘κ·Ό κ°€λŠ₯)
    public synchronized void increment() {
        count++;
        System.out.println(Thread.currentThread().getName() + " - Count: " + count);
    }
}

public class SynchronizedExample {
    public static void main(String[] args) {
        Counter counter = new Counter();

        Runnable task = () -> {
            for (int i = 0; i < 5; i++) {
                counter.increment();
            }
        };

        Thread t1 = new Thread(task);
        Thread t2 = new Thread(task);

        t1.start();
        t2.start();
    }
}

πŸ“Œ synchronized ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜λ©΄ ν•œ λ²ˆμ— ν•˜λ‚˜μ˜ μŠ€λ ˆλ“œλ§Œ increment()λ₯Ό μ‹€ν–‰
πŸ“Œ Race Condition을 λ°©μ§€ν•˜μ—¬ 데이터 일관성을 μœ μ§€


πŸ”₯ 5. 정리

βœ… μŠ€λ ˆλ“œ(Thread)λŠ” ν•˜λ‚˜μ˜ ν”„λ‘œκ·Έλž¨ λ‚΄μ—μ„œ μ‹€ν–‰λ˜λŠ” 독립적인 흐름
βœ… λ©€ν‹°μŠ€λ ˆλ“œλ₯Ό μ‚¬μš©ν•˜λ©΄ μ—¬λŸ¬ μž‘μ—…μ„ λ™μ‹œμ— μˆ˜ν–‰ κ°€λŠ₯
βœ… Threadλ₯Ό μƒμ†λ°›κ±°λ‚˜, Runnable을 κ΅¬ν˜„ν•˜μ—¬ μŠ€λ ˆλ“œ 생성 κ°€λŠ₯
βœ… start()λ₯Ό ν˜ΈμΆœν•˜λ©΄ μƒˆλ‘œμš΄ μŠ€λ ˆλ“œκ°€ 싀행됨
βœ… sleep(), join(), synchronized 등을 ν™œμš©ν•˜μ—¬ μŠ€λ ˆλ“œ μ œμ–΄ κ°€λŠ₯
βœ… λ©€ν‹°μŠ€λ ˆλ“œ ν™˜κ²½μ—μ„œλŠ” 동기화(synchronized)λ₯Ό μ‚¬μš©ν•˜μ—¬ 데이터 좩돌 λ°©μ§€

profile
Here, My Pale Blue.🌏

0개의 λŒ“κΈ€