소프트웨어 개발을 하다 보면 "스레드(Thread)"라는 용어를 자주 접하게 됩니다. 특히, 운영체제(Operating System, OS)와 멀티스레딩 프로그래밍에서 중요한 개념입니다. 이번 포스팅에서는 스레드의 개념, 싱글 스레드 vs 멀티 스레드, 장점과 단점, 그리고 실전 예제까지 한 번에 정리해보겠습니다.
1. 스레드(Thread)란?
스레드는 프로세스(Process) 내에서 실행되는 가장 작은 작업 단위입니다.
✅ 프로세스(Process) vs. 스레드(Thread)
개념 프로세스(Process) 스레드(Thread)
정의 | 실행 중인 프로그램 | 프로세스 내에서 실행되는 작은 작업 흐름 |
독립성 | 서로 독립적 (메모리 공간 분리) | 같은 프로세스 내에서 메모리를 공유 |
자원 할당 | 별도의 메모리 공간 할당 | 스레드끼리 메모리(Heap, Data)를 공유 |
실행 단위 | 하나 이상의 스레드를 가짐 | 한 프로세스 내에서 여러 개의 스레드가 실행 가능 |
예시 | 웹 브라우저(크롬, 엣지), 엑셀, 게임 | 브라우저의 여러 탭, 동영상 플레이어의 오디오 & 비디오 처리 |
즉, 스레드는 하나의 프로세스 내에서 실행되는 독립적인 실행 흐름이라고 볼 수 있습니다.
2. 싱글 스레드(Single Thread) vs 멀티 스레드(Multi Thread)
스레드는 크게 싱글 스레드와 멀티 스레드로 구분됩니다.
✅ 싱글 스레드(Single Thread)
- 한 번에 하나의 작업만 실행 가능
- 하나의 코드가 실행되는 동안 다른 작업이 대기해야 함
- 자바스크립트(JavaScript), 파이썬(Python 기본 실행 환경) 등에서 사용됨
싱글 스레드 예제 (JavaScript)
console.log("작업 1 시작");
setTimeout(() => {
console.log("비동기 작업 실행");
}, 1000);
console.log("작업 2 진행 중");
✅ 출력 결과
작업 1 시작
작업 2 진행 중
(1초 후)
비동기 작업 실행
👉 setTimeout()은 비동기 함수로 동작하지만, 싱글 스레드 환경에서는 논블로킹 방식으로 동작하여 먼저 실행할 수 있는 코드가 실행됩니다.
✅ 멀티 스레드(Multi Thread)
- 하나의 프로세스에서 여러 개의 작업을 동시에 실행 가능
- CPU를 효율적으로 활용하여 성능을 향상시킬 수 있음
- Java, C++, Python (threading 사용) 등에서 지원됨
멀티 스레드 예제 (Java)
class MyThread extends Thread {
public void run() {
System.out.println("새로운 스레드 실행 중...");
}
}
public class MultiThreadExample {
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start(); // 새로운 스레드 실행
System.out.println("메인 스레드 실행 중...");
}
}
✅ 출력 결과 (실행할 때마다 다를 수 있음)
메인 스레드 실행 중...
새로운 스레드 실행 중...
👉 thread.start()를 호출하면 새로운 스레드가 생성되어 메인 스레드와 동시에 실행됩니다.
3. 스레드의 장점과 단점
✅ 장점
- 멀티 스레드 환경에서는 여러 작업을 동시에 처리하여 속도 향상 (병렬 처리 가능)
- 자원을 공유하므로 메모리 사용량이 적음 (같은 프로세스 내에서 메모리 공유)
- UI/UX가 부드럽게 동작 (예: 웹 브라우저의 여러 탭 동작)
❌ 단점
- 동기화(Synchronization) 문제가 발생할 수 있음 (여러 스레드가 같은 데이터를 수정할 때 충돌 가능)
- 디버깅이 어려움 (멀티 스레드는 상태 추적이 어려움)
- 스레드 생성 및 관리 비용(오버헤드) 발생 (스레드가 많아질수록 리소스 사용 증가)
4. 싱글 스레드 vs 멀티 스레드 언제 사용할까?
상황 | 싱글 스레드 | 멀티 스레드 |
단순한 작업 | ✅ 적합 | ❌ 불필요 |
네트워크 요청 | ✅ 적합 (비동기 처리) | ❌ 불필요 |
연산 집약적 작업 (ex. 영상 렌더링, 머신러닝) | ❌ 느림 | ✅ 적합 |
UI가 있는 프로그램 (ex. 게임, 웹 브라우저) | ❌ 느림 | ✅ 적합 |
- 싱글 스레드는 간단한 프로그램, 비동기 처리 기반의 서비스에 적합합니다.
- 멀티 스레드는 CPU 부하가 큰 작업(대량 연산, 멀티미디어 처리)에 적합합니다.
5. 이벤트 루프(Event Loop)와 싱글 스레드의 관계
자바스크립트가 싱글 스레드이지만, 비동기 처리가 가능한 이유는 이벤트 루프(Event Loop) 덕분입니다.
- 콜 스택(Call Stack)
- 동기적으로 실행되는 코드들은 Call Stack에 쌓이고, 순차적으로 실행됩니다.
- 웹 API(Web APIs)
- setTimeout, fetch, addEventListener 같은 비동기 함수들은 브라우저의 Web API에서 관리됩니다.
- 태스크 큐(Task Queue)
- 비동기 작업이 완료되면, 그 콜백 함수는 태스크 큐에 저장됩니다.
- 이벤트 루프(Event Loop)
- 이벤트 루프는 콜 스택이 비었을 때, 태스크 큐에서 작업을 가져와 실행합니다.
이 덕분에 자바스크립트는 싱글 스레드이지만, 비동기 처리를 통해 마치 여러 작업을 동시에 수행하는 것처럼 동작할 수 있습니다.
정리하자면,
- 자바스크립트는 싱글 스레드이지만, 동기(Synchronous) 코드와 비동기(Asynchronous) 코드가 모두 실행될 수 있는 언어입니다.
- 동기적 실행은 한 줄씩 차례대로 실행되지만, 비동기 함수(setTimeout, fetch, Promise 등) 를 사용하면 특정 작업을 기다리지 않고 다른 코드가 먼저 실행될 수 있습니다.
- 이를 관리하는 것이 이벤트 루프(Event Loop) 이며, 이 구조 덕분에 싱글 스레드에서도 비동기 처리가 가능합니다.
📌 추가로 보면 좋은 개념
- 프로세스(Process)와 스레드(Thread)의 차이점
- 멀티 스레딩에서 발생할 수 있는 동기화 문제와 해결 방법 (Mutex, Semaphore)
- JavaScript의 이벤트 루프(Event Loop)와 비동기 처리 방식