Thread thread = Thread.ofVirtual().name("myVirtual").start(runnable);
Thread thread = Thread.ofVirtual().name("myVirtual1").unstarted(runnable);
thread.start();
ThreadFactory factory = Thread.ofVirtual().name("myVirtual-", 0).factory();
try (ExecutorService executorService = Executors.newThreadPerTaskExecutor(factory)) {
for (int i = 0; i < 10; i++) {
executorService.submit(runnable);
}
}
private final Runnable runnable = new Runnable() {
@Override
public void run() {
log.info("1) run. thread: " + Thread.currentThread());
synchronized (this) { // <--- synchronized block cause pinning
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
log.info("2) run. thread: " + Thread.currentThread());
}
};
-Djdk.tracePinnedThreads=full or -Djdk.tracePinnedThreads=short
private final ReentrantLock lock = new ReentrantLock();
private final Runnable runnable = new Runnable() {
@Override
public void run() {
log.info("1) run. thread: " + Thread.currentThread());
lock.lock(); // <-- use ReentrantLock instead of sycchronized block
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
lock.unlock();
}
log.info("2) run. thread: " + Thread.currentThread());
}
};
jcmd <PID> Thread.dump_to_file -format=text <file>
spring:
threads:
virtual:
enabled: true
spring:
task:
execution:
thread-name-prefix: myTask-
spring:
task:
scheduling:
thread-name-prefix: myScheduler-
spring:
main:
keep-alive: true
https://docs.oracle.com/en/java/javase/21/core/virtual-threads.html