티스토리 뷰
📖 Java에서 스레드를 만드는 방법
Thread 클래스 상속
public class MyThread extends Thread {
public void run() {
System.out.println("스레드 실행");
}
public static void main(String[] args) {
MyThread t = new MyThread(); // 스레드 객체 생성
t.start(); // run() 실행 (스레드 시작)
}
}
✔️ Thread 클래스를 상속받고, run() 메서드를 오버라이딩
✔️ start()를 호출하면 새로운 스레드에서 run()이 실행됨
✔️ 간단한 방법이지만, 이미 다른 클래스를 상속 중이라면 사용 불가(다중 상속x)
Runnable 인터페이스 구현
public class MyRunnable implements Runnable {
public void run() {
System.out.println("스레드 실행");
}
public static void main(String[] args) {
Thread t = new Thread(new MyRunnable()); // Runnable 구현체 전달
t.start(); // run() 실행
}
}
✔️ Runnable 인터페이스를 구현하고, run() 메서드 정의
✔️ Thread 생성자에 전달해서 실행
✔️ 상속을 사용하지 않기 때문에 다른 클래스 상속과 함께 사용이 가능해서 더 선호되는 방법
📖 스레드 풀
스레드 풀이란?
미리 일정 개수의 스레드를 생성하여 관리하는 기법이다. 이렇게 생성된 스레드들은 작업을 할당받기 위해 대기 상태에 있게 되는데, 작업이 발생하면 대기중인 스레드 중 하나를 선택하여 작업을 수행한다. 작업이 완료되면 해당 스레드는 다시 대기 상태로 돌아가고, 새로운 작업을 할당받을 준비를 한다.
사용 목적
스레드 생성 및 삭제에 따른 오버헤드를 줄일 수 있고, 특정 시점에 동시에 처리할 수 있는 작업의 개수를 제한할 수 있다. 이를 통해 시스템의 자원을 효율적으로 관리하고 성능을 향상시킬 수 있다.
📖 프레임워크에서의 스레드 풀
Q. 스프링과 같은 프레임워크에서는 스레드 풀의 개수를 수백개 이상으로 운영한다. 이는 Context Switching이 일어남에도 불구하고 이런 선택을 내린 것인데, 그 이유는?
A. 대부분의 웹 요청이 CPU 계산보다는 DB 조회나 외부 API 호출 같은 I/O 작업이 많기 때문이다. I/O 작업은 처리보다 대기 시간이 길어, 하나의 스레드가 응답을 기다리는 동안 다른 스레드가 다른 요청을 처리할 수 있도록 여러 개의 스레드를 운영하는 것이 효율적이다.
스레드가 많아지면 Context Switching 비용이 발생하지만 이는 몇 마이크로초 수준으로 작고, I/O 대기 시간은 수 밀리초 이상 걸리기 때문에 일정 수 이상의 스레드를 유지하는 것이 성능과 응답 속도 측면에서 유리하다.
'Study > CS 스터디 - Java' 카테고리의 다른 글
| JVM & GC (0) | 2025.04.09 |
|---|---|
| 동시성 (0) | 2025.04.03 |
| 컬렉션 (0) | 2025.03.27 |
| 람다, 스트림, 어노테이션 (0) | 2025.03.20 |
| 문자열, 예외, 제네릭 (0) | 2025.03.19 |