236. Avoiding pinning via locking
Remember from Chapter 10, Problem 213, that a virtual thread is pinned (not unmounted from its carrier thread) when the execution goes through a synchronized
block of code. For instance, the following Runnable
will cause virtual threads to be pinned:
Runnable task1 = () -> {
synchronized (Main.class) {
try {
Thread.sleep(1000);
} catch (InterruptedException ex) { /* handle it */ }
logger.info(() -> "Task-1 | "
+ Thread.currentThread().toString());
}
};
The synchronized
block contains a blocking operation (sleep()
), but the virtual thread that hits this point of execution is not unmounted. It is pinned on its carrier thread. Let’s try to capture this behavior via the following executor:
private static final int NUMBER_OF_TASKS = 25;
try (ExecutorService executor
= Executors.newVirtualThreadPerTaskExecutor()) {
for (int i = 0; i < NUMBER_OF_TASKS; i++) {
executor.submit...