Java 21 virtual threads allow the JVM to optimize the usage of OS threads, by mounting and unmounting them on an OS thread when needed, and making
them more efficient when dealing with blocking operations such as HTTP requests or I/O.
However, when code is executed inside a synchronized
block or synchronized
method, the virtual thread stays pinned to the
underlying OS thread and cannot be unmounted during a blocking operation. This will cause the OS thread to be blocked, which can impact the
scalability of the application.
Therefore, virtual threads should not execute code that contains synchronized
blocks or invokes synchronized
methods.
Platform threads should be used in these cases.
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(){}