Java Virtual Threads (Project Loom): Concurrency ยุคใหม่
#java13 เม.ย. 2569
Virtual Threads คืออะไร
Virtual Threads (Java 21) เป็น lightweight threads ที่ JVM จัดการเอง ไม่ผูกกับ OS thread ทำให้สร้างได้หลายล้าน thread โดยไม่กิน memory มาก
Platform Thread vs Virtual Thread
Platform Thread:
- ผูกกับ OS thread 1:1
- สร้างได้ไม่กี่พัน
- Memory ~1MB ต่อ thread
- Blocking I/O ทำให้ OS thread ว่าง
Virtual Thread:
- JVM จัดการ M:N mapping
- สร้างได้หลายล้าน
- Memory ~few KB ต่อ thread
- Blocking I/O ไม่ block OS thread
สร้าง Virtual Thread
// สร้าง virtual thread
Thread vt = Thread.ofVirtual().start(() -> {
System.out.println("Virtual thread: " + Thread.currentThread());
});
// Virtual thread factory
ThreadFactory factory = Thread.ofVirtual().factory();
Thread t = factory.newThread(() -> System.out.println("Hello!"));
t.start();
// ExecutorService กับ virtual threads
try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {
for (int i = 0; i < 1_000_000; i++) {
executor.submit(() -> {
Thread.sleep(Duration.ofSeconds(1));
return "done";
});
}
}
// สร้าง 1 ล้าน virtual threads ได้สบาย!
ตัวอย่าง Web Server
// Spring Boot 3.2+ - เปิดใช้ virtual threads
@Bean
public TomcatProtocolHandlerCustomizer<?> protocolHandlerVirtualThreadExecutorCustomizer() {
return protocolHandler -> {
protocolHandler.setExecutor(Executors.newVirtualThreadPerTaskExecutor());
};
}
// หรือใน application.properties
// spring.threads.virtual.enabled=true
Structured Concurrency
import java.util.concurrent.StructuredTaskScope;
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
Future<User> userFuture = scope.fork(() -> fetchUser(1));
Future<List<Order>> ordersFuture = scope.fork(() -> fetchOrders(1));
scope.join(); // รอทั้งคู่
scope.throwIfFailed(); // throw ถ้ามี error
User user = userFuture.resultNow();
List<Order> orders = ordersFuture.resultNow();
return new UserProfile(user, orders);
}
Performance Comparison
// Platform threads - จำกัดที่ ~10,000
try (ExecutorService exec = Executors.newFixedThreadPool(10_000)) {
// ...
}
// Virtual threads - ได้ 1,000,000+
try (ExecutorService exec = Executors.newVirtualThreadPerTaskExecutor()) {
for (int i = 0; i < 1_000_000; i++) {
exec.submit(this::doWork);
}
}
ข้อควรระวัง
// ❌ อย่าใช้ synchronized กับ blocking I/O ใน virtual thread
synchronized (lock) {
Thread.sleep(1000); // pin carrier thread!
}
// ✅ ใช้ ReentrantLock แทน
ReentrantLock lock = new ReentrantLock();
lock.lock();
try {
Thread.sleep(1000); // ไม่ pin carrier thread
} finally {
lock.unlock();
}
สรุป
Virtual Threads เปลี่ยนวิธีเขียน concurrent Java ไปมาก ทำให้เขียน blocking code ได้โดยไม่เสีย performance เหมาะกับ I/O-intensive applications เช่น web servers, microservices ครับ