싱글 스레드

이동영·2026년 2월 16일

웹개발

목록 보기
36/36

Java Spring MVC 환경에서 우리는 ThreadLocal을 사용하고, 스레드 안전성(Thread-safety)을 위해 ConcurrentHashMap을 고민한다. 하지만 Node.js는 "메인 스레드는 하나뿐"이라는 파격적인 설계를 택했다. 왜 그랬을까?

1. Java의 멀티 스레드 vs Node.js의 싱글 스레드

  • Java (Multi-Thread) : 요청이 올 때마다 스레드를 새로 생성하거나 풀에서 꺼낸다.
  • 장점 : 멀티코어 CPU를 풀로 활용해 복잡한 연산을 병렬로 처리한다.
  • 단점 : 스레드가 많아질수록 컨텍스트 스위칭(Context Switching) 비용이 발생하고 메모리 점유율이 높아진다. (스레드 하나당 보통 1MB 정도의 스택 메모리 점유)
  • Node.js (Single-Thread) : 사용자의 요청을 받는 '이벤트 루프'가 단 하나의 스레드에서만 돌아간다.
  • 장점: 컨텍스트 스위칭 오버헤드가 없고, 자원 소모가 매우 적다. 공유 자원에 대한 동기화(synchronized) 문제에서 자유롭다.
  • 단점: 메인 스레드가 뻗으면 서버 전체가 뻗는다. CPU 연산이 헤비한 작업에 취약하다.

2. 진짜 스레드가 하나뿐인가? (Libuv의 비밀)

엄밀히 말하면 "우리가 작성한 자바스크립트 코드가 실행되는 스레드"가 하나인 것이다. Node.js 내부(C++로 작성된 Libuv)에는 여전히 Thread Pool이 존재한다.

  1. 메인 스레드 : 이벤트 루프를 돌리며 요청을 받고 응답을 보낸다.
  2. 워커 스레드 (내부) : 암호화, 파일 I/O, 압축 등 무거운 작업은 Libuv가 관리하는 별도의 스레드에서 처리한다.

즉, Node.js는 "주문받는 점원(메인 스레드)은 한 명이지만, 주방 안에서 실제 요리를 하는 요리사(내부 스레드)는 여러 명"인 구조다.

3. 주의: 싱글 스레드의 적

싱글 스레드 모델에서 가장 피해야 할 것은 'CPU Intensive' 작업이다.

  • 예 : 수백만 개의 배열 정렬, 고해상도 이미지 프로세싱 등.
  • 이런 코드를 실행하면 메인 스레드가 점유되어 다른 사용자의 '조회' 요청조차 처리하지 못하는 병목 현상이 발생한다.

4. 멀티 프로세싱

그렇다면 점원 여러 명(멀티 스레드)이 모두 논블로킹 방식으로 주문을 받으면 좋지 않을까? 실제로 그렇다. 다만, 멀티 스레드 방식으로 프로그래밍을 하는 것은 상당히 어렵기 때문에, 멀티 프로세싱 방식을 대신 사용한다.
I/O 요청엔는 멀티 프로세싱이 더 효율적이기도 하다.

멀티 스레딩멀티 프로세싱
하나의 프로세스 안에서 여러 개의 스레드 사용여러 개의 프로세스 사용
CPU 작업이 많이 사용될 때 사용I/O 요청이 많을 때 사용
프로그래밍이 어려움비교적 쉬움

I/O 작업을 처리할 때는 멀티 스레딩보다 멀티 프로세싱이 효율적이므로 노드는 멀티 프로세싱을 많이 한다.

0개의 댓글