Java virtual threads enable the JVM to optimize the use of OS threads by mounting and unmounting them as needed. This makes them more efficient
when dealing with blocking operations such as I/O or HTTP requests.
This rule applies only to code running on Java versions older than 24. Since Java 24, virtual threads are no longer pinned when executing
synchronized
code.
For Java version 21 to 23, when code is executed inside a synchronized
block or method, the virtual thread remains pinned to its
underlying OS thread and cannot be unmounted during a blocking operation. This causes the OS thread to be blocked, which can impact the scalability of
the application.
Therefore, in environments running a Java version below 24, virtual threads should not execute code that contains synchronized
blocks
or invokes synchronized
methods. Platform threads should be used in these cases instead.
This rule raises an issue when a virtual thread contains synchronized
blocks or invokes synchronized
methods.
Code examples
Noncompliant code example
void enqueue(){
Thread.startVirtualThread(() -> { // Noncompliant; use a platform thread instead
setupOperations();
dequeLogic();
}
});
}
Compliant solution
void enqueue(){
new Thread(() -> {
synchronized {
setupOperations();
dequeLogic();
}
}).start();
}
Noncompliant code example
void enqueue2(){
Thread.startVirtualThread(() -> { // Noncompliant; use a platform thread instead of a virtual one
if(someCondition){
synchronizedMethod();
}else{
defaultLogic();
}
});
}
synchronized void synchronizedMethod(){}
void defaultLogic(){}
Compliant solution
void enqueue2(){
new Thread(() -> {
if(someCondition){
synchronizedMethod();
}else{
defaultLogic();
}
}).start();
}
synchronized void synchronizedMethod(){}
void defaultLogic(){}