백엔드 엔지니어 이재혁
Thread와 스케쥴링 본문
CPU를 시분할 해서 멀티 태스킹할 때, 프로세스 단위가 아닌 스레드 단위로 작업을 나눈다.

위와 같이, Process 1 에는 Thread A 하나만 있고, Process 2 에는 Thread B1, B2 두 개가 있을 때
CPU 코어 1개가 Process 1과 2를 시분할 멀티 태스킹한다고 가정하면,
Thread A -> B1 -> B2 이렇게 Thread를 기준으로 쭉 실행한다.
Process 1 (Thread A) -> Process 2 (Thread B1) -> Process1 (Thread A) -> Process 2 (Thread B2)
이렇게 프로세스 기준으로 실행하는 것이 아니다.
Process 자체는 운영체제에 의해 스케쥴링되어 직접 실행되는 것이 아니고, Process 안에 있는 Thread를 실행한다.
참고 - 실무 이야기
이상적으로는 CPU 코어 수 + 1개 정도로 스레드를 맞추면 특정 스레드가 잠시 대기할 때 남은 스레드를 활용할 수 있다.
항상 맞는 것은 아니다! CPU-bound 작업 / I/O-bound 작업 에 따라 다름. (bound: 묶여있는)
특히 WAS는 I/O 바운드 작업이 많다.
일반적인 Java WAS의 경우, 사용자 요청 1개 당 1개의 Thread가 필요하다. 다만, I/O 바운드 작업이 많기 때문에 CPU 코어 = 사용자 요청 수를 맞추는 것은 오히려 CPU를 잘 활용하지 못하는 것이다.
실무에서는 성능 테스트를 통해 최적의 스레드 수를 찾는 것이 이상적이다.
정리
CPU-바운드 작업: CPU 코어 수 + 1개
- CPU를 거의 100% 사용하는 작업이므로 스레드를 CPU 숫자에 최적화
I/O-바운드 작업: CPU 코어 수 보다 많은 스레드를 생성, CPU를 최대한 사용할 수 있는 숫자까지 스레드 생성
- CPU를 많이 사용하지 않으므로 성능 테스트를 통해 CPU를 최대한 활용하는 숫자까지 스레드 생성
- 단 너무 많은 스레드를 생성하면 컨텍스트 스위칭 비용도 함께 증가 - 적절한 성능 테스트 필요
WAS 라도 CPU 바운드 작업이 많을 수도 있다. 어떤 코드냐에 따라 다 다르다.