Java 21 virtual thread'ler nedir? Platform thread'lerden farkı nedir ve hangi durumlarda dikkatli olmak gerekir?
Cevap
Virtual thread'ler (Project Loom, Java 21'de final), JVM tarafından yönetilen çok hafif thread'lerdir. Bir OS thread'ine bire bir bağlı değildirler; az sayıda carrier (platform) thread üzerinde çalışırlar. Bloklayan bir I/O çağrısında virtual thread carrier'dan ayrılır (unmount) ve carrier başka bir işe geçer.
| Platform thread | Virtual thread | |
|---|---|---|
| Eşleme | 1 Java thread = 1 OS thread | Çok sayıda virtual thread, az carrier |
| Bellek | Yaklaşık 1 MB stack rezervi | Birkaç KB, heap'te büyür |
| Sayı | Binler | Milyonlar |
| Uygun iş | CPU-bound | Bloklayan I/O (DB, HTTP) |
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
for (int i = 0; i < 10_000; i++) {
executor.submit(() -> httpClient.send(request, ofString()));
}
}Spring Boot 3.2+ ile spring.threads.virtual.enabled=true ayarı Tomcat isteklerini ve @Async görevlerini virtual thread'lerde çalıştırır.
Faydası
Reactive programlamanın (WebFlux) karmaşıklığına girmeden, klasik bloklayan "thread-per-request" koduyla yüksek eşzamanlılık elde edilir.
Dikkat edilmesi gerekenler
- Pinning: Java 21-23'te
synchronizedblok içinde bloklayan çağrı virtual thread'i carrier'a sabitler; ölçeklenme kaybolur. Bu sorun Java 24 (JEP 491) ile büyük ölçüde giderildi. Eski sürümlerdeReentrantLockkullanın. - Pool'lamayın: virtual thread'ler ucuzdur, her görev için yenisi açılır.
- Downstream limitleri hâlâ geçerli: 10.000 virtual thread aynı anda DB'ye gitmeye çalışırsa connection pool (ör. HikariCP 10 bağlantı) darboğaz olur. Eşzamanlılığı
Semaphoreile sınırlayın. ThreadLocalile büyük nesne cache'lemek milyonlarca thread'de bellek patlatır; Java 25'te final olan ScopedValue daha uygundur.- CPU-bound işte fayda sağlamaz.
İlgili Java & Spring soruları
- ExecutorService ve CompletableFuture ile asenkron iş nasıl yapılır? Thread pool boyutunu nasıl belirlersiniz?
- JPA/Hibernate'te lazy ve eager loading farkı nedir? LazyInitializationException neden oluşur ve nasıl çözülür?
- @Transactional anotasyonu hangi durumlarda çalışmaz? Self-invocation, rollback kuralları ve propagation tuzaklarını açıklayın.
- Spring bean scope'ları nelerdir? Singleton bir bean'e prototype bean inject edilirse ne olur?
- Spring'de Dependency Injection nedir? Constructor injection neden field injection'a tercih edilir?
- Java'da Garbage Collection nasıl çalışır? G1 ve ZGC arasındaki farklar nelerdir, hangisini ne zaman seçersiniz?
Bu konuda başka bir soru biliyor musun?
Mülakatta karşılaştığın soruları ekle, onaylandıktan sonra yayına alınsın.