6 Mayıs 2024 Pazartesi

Virtual Threads - Thread Pinning

Thread Pinning 
Virtual Threads için JDK'daki bir çok kod baştan yazılmış. Böylece thread unloading işlemi yapılabiliyor.  Ancak bir kaç işlemde istisna var. Buna Thread Pinning deniliyor

1. Object.wait()
2. synchronized blok içinde
3. native metod çalıştırırken
4. UDP Sockets
5. Files & DNS

Açıklaması şöyle
Pinning describes the condition where a virtual thread, which maps the platform thread, is stuck to the carrier thread. It means that the virtual thread can’t be unmounted from the carrier threads because the state of it can’t be stored in the heap memory. The pinned thread prevents others from utilizing the same platform thread.
1. synchronized Thread Pinning
Açıklaması şöyle
Only one thread can enter it at a time. The other threads attempting to enter will be blocked until the current (running) thread exits. They would need an uninterrupted access to shared resources to prevent race conditions as well as an accurate state of the data.
Örnek
Şu kod carrier thread'i bloke eder
var e = Executors.newVirtualThreadPerTaskExecutor();
for (int i = 0; i < 1000; i++) {
    e.submit(() -> { new Test().test(); });
}
e.shutdown();
e.awaitTermination(1, TimeUnit.DAYS);

class Test {
  synchronized void test() {
    sleep(4000);
  }
}
synchronized yerine  ReentrantLock kullanılır. Şöyle yaparız
var e = Executors.newVirtualThreadPerTaskExecutor();
for (int i = 0; i < 1000; i++) {
    e.submit(() -> { new Test().test(); });
}
e.shutdown();
e.awaitTermination(1, TimeUnit.DAYS);

class Test {
  private ReentrantLock lock = new ReentrantLock();
  void test() {
    lock.tryLock();
    try {
      sleep(4000);
    } finally {
      lock.unlock();
    }
  }
}
MySQL-J JDBC sürücüsündeki bir açıklama şöyle
Synchronized blocks in the Connector/J code were replaced with ReentrantLocks. This allows carrier threads to unmount virtual threads when they are waiting on IO operations, making Connector/J virtual-thread friendly. Thanks to Bart De Neuter for contributing to this patch. ”

2. native method Thread Pinning
Açıklaması şöyle
This method lets you use code from other languages into your JAVA project, like C or C++. Native methods are invoked within the JAVA virtual machine but executed outside its control.
3. Sockets Thread Pinning
TCP socketlerini okurken Virtual Threads bloke olmuyor, ama UDP socketlerinde oluyor. Açıklaması şöyle
However, not all Java constructs have been retrofitted that way. Such operations include synchronized methods and code blocks. Using them causes the virtual thread to become pinned to the carrier thread. When a thread is pinned, blocking operations will block the underlying carrier thread-precisely as it would happen in pre-Loom times.
Eğer carrier therad'in bloke olma durumu varsa, virtual thread sayısı artırılır. En fazla kaç thread olabileceği  jdk.virtualThreadScheduler.maxPoolSize ile atanabilir

pinned thread Tracing
Açıklaması şöyle
Use the following JVM parameters as options to trace the pinned thread

-Djdk.tracePinnedThreads=full Prints a complete stack trace when a thread jams while pinned, highlighting native frames and frames holding monitors.

-Djdk.tracePinnedThreads=short Limits the output to just the problematic frames.