Virtual threads are very good at waiting while being blocked. Because the carrier thread will pick up/ mount a new virtual thread to run. There are cases when it doesn't happen and a virtual thread is not unmounted while it is blocked. When a virtual thread is blocked and stuck on a carrier thread, we call that virtual thread pinned to its carrier thread. Virtual threads that are planned hurt your scalability because those carrier threads cant pick up other virtual threads.
A virtual thread gets pinned when it encounters a method that does not support the unmounting and mounting process like some file IO operation or JNI calls. In this post, we look into how you can detect virtual threads that are pinned using two command line options.
You can use the following two run options to set the amount of information you want to see when a virtual thread gets pinned.
You can also set these two system properties if you prefer to use these instead of run options.
Full or short?
You can set the trace to either full or short. I added two examples of traces to give you an idea of what they look like. The first example shows you the full trace.
If you choose to use the short options, it will just show you the problematic frames.
To create these examples, I used the following code. At the time of writing the synchronized method causes the virtual threads to get pinned.
In this post, we looked at what pinned virtual threads are and how you can detect them using run options.