Virtual thread
기존 스레드 방식(Native thread)
기존에는 JVM 스레드가 커널 스레드에 1:1 대응되는 방식으로 사용되었습니다.
특징
- 가상 스레드에 비해 컨텍스트 스위치 비용이 큼
- 생성을 위해선 커널과 통신하여 스케줄링해야 하므로, 시스템 콜을 이용하기 때문에 생성 비용도 작지 않음
Virtual thread의 방식
특징
- 가상 스레드는 일반 스레드의 약 1%의 작은 메모리를 가지고 있기 때문에 컨텍스트 스위치 비용이 작음
- JVM을 통해 생성하므로 시스템 콜과 같은 커널 영역의 호출이 적음
동작과정
- runContinuation(실행될 virtual thread의 작업)을 carrier thread의 workQueue에 push
- Work queue에 있는 runContinuation들은 forkJoinPool에 의해 work stealing 방식으로 carrier thread에 의해 처리
- 처리되던 runContinuation들은 I/O, Sleep으로 인한 interrupt나 작업 완료 시, work queue에서 pop되어 park과정에 의해 다시 힙 메모리로 되돌아감
*work stealing: 한 스레드의 작업 queue가 비게 되면 다른 thread의 작업 queue에서 task를 가져와서 작업
장단점
장점
- 네트워크 IO 같은 interrupt 기간이 긴 작업에서 높은 효율을 보임
- Reactive 방식과 같이 기존에 MVC로 작성된 코드를 대부분 수정할 필요가 없으며, Reactive의 러닝커브의 부담을 질 필요가 없음
단점 및 주의사항
- CPU bound 작업에는 Native thread보다 비효율적
- 매우 많은 thread가 생성되기 때문에, thread마다 생성되는 Thread local의 사용에 매우 주의해야함 → Scoped Value라는 보완 방안 존재
- Pinned issue: synchronized, parallelStream, 네이티브 메서드를 사용하면 virtual thread가 carrier thread에 고정되므로 사용자제 → virtual thread에서 synchronized는 Reentrant lock으로 대체하면 방지가능
사용법
spring boot 3.2 이상
spring:
threads:
virtual:
enabled: true
Mysql connector/J 버전
implementation 'com.mysql:mysql-connector-j:9.+'
Mysql connector/J는 9.0.0 버전에서 synchronized를 Reentrant Lock으로 대체하여 virtual thread의 사용 효율을 늘렸다.
MySQL Connector/J 9.0.0 Release Notes
Reference.
[Project Loom] Virtual Thread에 봄(Spring)은 왔는가 | 카카오페이 기술 블로그
Java의 미래, Virtual Thread | 우아한형제들 기술블로그