Java 25 + Spring Boot 4.0.5로 VirtualThread (Project Loom)의 사용 및 활용을 시연하는 샘플 프로젝트입니다.
이 프로젝트는 Java의 VirtualThread 기능을 Spring Boot 환경에서 어떻게 활용하는지 실제 코드로 보여줍니다.
-
VirtualThread 기본 사용
@Async를 사용한 비동기 처리- ExecutorService를 통한 직접 VirtualThread 생성
- VirtualThread 풀 관리
-
Platform Thread vs VirtualThread
- 메모리 사용량 비교
- 성능 비교
- 스레드 생성 비용 차이
-
Thread Pinning 문제 및 해결
- Java 21의 synchronized 키워드 Thread Pinning
- Java 24의 synchronized 개선사항
- ReentrantLock을 사용한 해결책
- Lock 성능 비교
| 항목 | 버전 |
|---|---|
| Java | 25 |
| Spring Boot | 4.0.5 |
| Build Tool | Maven 3.6+ |
| Logging | SLF4J + Logback |
src/main/java/com/gracefulsoul/virtualthread/
├── VirtualThreadApplication.java # 메인 애플리케이션
├── controller/
│ └── VirtualThreadController.java # REST API 컨트롤러
└── service/
├── VirtualThreadBasicService.java # VirtualThread 기본 사용법
└── ThreadPinningService.java # Thread Pinning 관련 서비스
- Java 25 이상 설치
- Maven 3.6 이상
# 프로젝트 빌드
mvn clean package
# 애플리케이션 실행
mvn spring-boot:run
# 또는 JAR 파일로 실행
java -jar target/spring-virtual-thread-sample-1.0.0.jar# Health Check
curl http://localhost:8080/api/virtual-thread/health
# 비동기 작업 처리 (Task ID 지정)
curl http://localhost:8080/api/virtual-thread/async/1
# 메모리 사용량 비교 (스레드 개수 지정)
curl http://localhost:8080/api/virtual-thread/memory-comparison/10# Java 24+ synchronized 개선 시연
curl -X POST http://localhost:8080/api/virtual-thread/java24-improvement
# Lock 성능 비교 (작업 개수 지정)
curl http://localhost:8080/api/virtual-thread/lock-comparison/100
# Thread Pinning 감지
curl -X POST http://localhost:8080/api/virtual-thread/detect-pinning
# Java 버전별 차이점 조회
curl http://localhost:8080/api/virtual-thread/version-differences@Async("virtualThreadExecutor")
public CompletableFuture<String> processWithVirtualThread(int taskId) {
long threadId = Thread.currentThread().threadId();
boolean isVirtual = Thread.currentThread().isVirtual();
log.info("Task {} - Virtual: {}, ID: {}", taskId, isVirtual, threadId);
return CompletableFuture.completedFuture("Completed");
}try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {
IntStream.range(0, 10).forEach(i -> {
executor.submit(() -> {
log.info("Task {} - Virtual: {}", i,
Thread.currentThread().isVirtual());
});
});
}private final ReentrantLock lock = new ReentrantLock();
public void threadSafeMethod(int taskId) {
lock.lock();
try {
// Critical section - VirtualThread pinning 없음
Thread.sleep(100);
} finally {
lock.unlock();
}
}| 특성 | Platform Thread | VirtualThread |
|---|---|---|
| 메모리 | ~2MB | ~1KB |
| 생성 시간 | 느림 | 빠름 |
| 컨텍스트 스위칭 | 비쌈 | 저렴함 |
| 동시 생성 개수 | 수천 개 | 수백만 개 |
| I/O 블로킹 | OS 스레드 블록 | 가상 스레드만 블록 |
| Thread Pinning | 없음 | synchronized 사용 시 발생 |
synchronized 키워드 사용 시 VirtualThread가 Carrier Thread(Platform Thread)에 고정되어 다른 VirtualThread가 사용할 수 없는 문제 발생
// Java 21에서 Thread Pinning 발생
public synchronized void criticalSection() {
// VirtualThread가 여기에 고정됨
}synchronized 키워드가 자동으로 최적화되어 간단한 경우에는 Thread Pinning 없음
ReentrantLock 사용
private final ReentrantLock lock = new ReentrantLock();
public void criticalSection() {
lock.lock();
try {
// Thread Pinning 없음
} finally {
lock.unlock();
}
}spring:
threads:
virtual:
enabled: true
application:
name: spring-virtual-thread-sample
server:
tomcat:
threads:
max: 200
min-spare: 10프로젝트에 포함된 성능 테스트를 실행하여 Platform Thread와 VirtualThread의 성능 차이를 확인할 수 있습니다.
# 메모리 사용량 비교 테스트
curl http://localhost:8080/api/virtual-thread/memory-comparison/1000
# Lock 성능 비교 테스트
curl http://localhost:8080/api/virtual-thread/lock-comparison/10000- Project Loom - OpenJDK
- Java 21 Release Notes
- Java 24 Release Notes
- Spring Framework 4.0 Release Notes
- Virtual Threads - Java Documentation
MIT License
GracefulSoul (Kim)