83 lines
2.2 KiB
Plaintext
83 lines
2.2 KiB
Plaintext
== Why is this an issue?
|
|
|
|
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
|
|
|
|
[source,java,diff-id=1,diff-type=noncompliant]
|
|
----
|
|
void enqueue(){
|
|
Thread.startVirtualThread(() -> { // Noncompliant; use a platform thread instead
|
|
setupOperations();
|
|
dequeLogic();
|
|
}
|
|
});
|
|
}
|
|
----
|
|
|
|
==== Compliant solution
|
|
|
|
[source,java,diff-id=1,diff-type=compliant]
|
|
----
|
|
void enqueue(){
|
|
new Thread(() -> {
|
|
synchronized {
|
|
setupOperations();
|
|
dequeLogic();
|
|
}
|
|
}).start();
|
|
}
|
|
----
|
|
|
|
==== Noncompliant code example
|
|
|
|
[source,java,diff-id=2,diff-type=noncompliant]
|
|
----
|
|
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
|
|
|
|
[source,java,diff-id=2,diff-type=compliant]
|
|
----
|
|
void enqueue2(){
|
|
new Thread(() -> {
|
|
if(someCondition){
|
|
synchronizedMethod();
|
|
}else{
|
|
defaultLogic();
|
|
}
|
|
}).start();
|
|
}
|
|
synchronized void synchronizedMethod(){}
|
|
void defaultLogic(){}
|
|
----
|
|
|
|
== Resources
|
|
|
|
=== Documentation
|
|
|
|
* Java Documentation - https://openjdk.org/jeps/444#:~:text=There%20are%20two,by%20capturing%20carriers[Virtual threads, pinning scenarios] |