728x90
[Java] 🧵 Thread 기본 개념
✅ 간단 정리
항목 | 설명 |
Thread 개념 | 실행 단위. 기본은 main 스레드 |
생성 방법 | Thread 상속 vs Runnable 구현 |
실행과 종료 | start()로 실행, 안전하게 종료 처리 필요 |
동기화 | 공유 자원 보호를 위한 synchronized |
데몬 스레드 | 백그라운드 보조 역할, main 종료 시 자동 종료 |
🔍 Thread란?
Thread(스레드)는 프로세스 내에서 실행되는 최소 실행 단위를 말한다. 자바 프로그램은 main
스레드에서 시작하며, 동시에 여러 작업을 병렬로 처리하고 싶다면 멀티스레딩(Multithreading)을 활용한다.
멀티스레딩은 UI 응답성, 백그라운드 처리, 서버 동시 요청 처리 등 다양한 상황에서 성능과 효율을 극대화할 수 있게 해 준다.
⚙️ 자바에서 Thread 만드는 2가지 방법
1. Thread 클래스 상속
public class MyThread extends Thread {
@Override
public void run() {
System.out.println("Thread 실행 중!");
}
}
new MyThread().start(); // 새로운 스레드에서 실행
2. Runnable 인터페이스 구현
public class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("Runnable 실행 중!");
}
}
new Thread(new MyRunnable()).start(); // 새로운 스레드에서 실행
🧠 run() vs start()
Thread t = new Thread(() -> System.out.println("실행"));
t.run(); // 그냥 일반 메서드 실행 (main 스레드에서 실행)
t.start(); // 별도 스레드에서 비동기 실행 ✅
- run() : 일반 메서드를 호출하는 것과 같음
- start() : 새로운 스레드를 생성하고 run()을 비동기적으로 실행
⏱ Thread 상태 (Life Cycle)
상태 | 설명 |
NEW | Thread 객체 생성만 된 상태 |
RUNNABLE | 실행 대기 또는 실행 중 |
BLOCKED | lock을 획득하지 못해 대기 중 |
WAITING | 특정 조건이나 notify 없이 무기한 대기 중 |
TIMED_WAITING | 일정 시간 동안 대기 중 (sleep, join 등) |
TERMINATED | 작업이 종료되어 스레드도 종료됨 |
🔒 동기화 (synchronized)
여러 스레드가 공유 자원을 동시에 접근할 때 Race Condition(경쟁 상태)이 발생할 수 있으므로, 필요시 동기화 처리가 필요하다.
public synchronized void increment() {
count++;
}
synchronized(lockObject) {
// 임계영역
}
🧷 안전한 종료 방법
스레드를 강제로 종료하는 stop()
메서드는 deprecated 되었기 때문에, 안전하게 종료하려면 volatile
변수나 interrupt()
방식으로 제어해야 한다.
class MyThread extends Thread {
private volatile boolean running = true;
public void run() {
while (running) {
// 작업 수행
}
}
public void stopRunning() {
running = false;
}
}
👻 데몬(Daemon) 스레드란?
데몬이란 그리스 신화에서 신과 인간 사이의 중간적 존재로, 보이지 않게 활동하며 일상적인 일들을 도움을 주는 존재로 컴퓨터 과학에서의 데몬 스레드는 사용자에게 직접적으로 보이지 않으면서 시스템의 백그라운드에서 작업을 수행하는 것을 뜻한다. 보조하는 역할이기 때문에 메인 스레드가 종료되면 데몬 스레드도 자동 종료가 된다. 따라서 데몬 스레드는 절대 주 작업에 사용되서는 안된다.
Thread daemonThread = new Thread(() -> {
while (true) {
System.out.println("데몬 스레드 실행 중...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
break;
}
}
});
daemonThread.setDaemon(true); // 반드시 start() 전에 설정해야 함
daemonThread.start();
🚀 실무에서는 Thread 직접 쓸까?
요즘 실무에서는 Thread를 직접 생성하기보단, 스레드 재사용, 예외 처리, 스케줄링 등을 쉽게 할 수 있게 도와주고, 안정성과 유지보수성이 높은 고수준 API를 더 자주 쓴다.
- ExecutorService
스레드를 직접 생성하지 않고 풀(Pool)을 이용해 작업을 관리하는 고수준 스레드 실행기 - CompletableFuture
비동기 작업을 체이닝과 조합으로 구성할 수 있는 Future의 확장형 - ScheduledExecutorService
일정 시간 후 또는 주기적으로 작업을 실행할 수 있는 스케줄링 지원 Executor - ForkJoinPool
작업을 작은 단위로 분할하고 병렬로 처리하는 데 최적화된 스레드 풀로, divide-and-conquer에 적합
728x90
'Backend > Java' 카테고리의 다른 글
[Java] 🚦 자바 메모리 가시성(Java Memory Visibility) (1) | 2025.04.20 |
---|---|
[Java] ☕ Thread 정리: 메서드, 생명주기, 제어 방법 (0) | 2025.04.07 |
[Java] (2) 시간, 날짜 관련 API(LocalTime, LocalDate, LocalDateTime) (0) | 2023.08.20 |
[Java] (1) 시간, 날짜 관련 API(LocalTime, LocalDate, LocalDateTime) (0) | 2023.08.19 |
[Java] 자바 8 - 올바른 Optional 사용법 (0) | 2023.08.13 |