update AvoidSynchronizedAtMethodLevel message to mention ReentrantLock

see https://openjdk.org/jeps/8337395
This commit is contained in:
Charles Honton
2024-08-21 14:27:02 -07:00
parent 07f96e79ad
commit 3dd47a3b94

View File

@ -12,13 +12,13 @@ Rules that flag issues when dealing with multiple threads of execution.
<rule name="AvoidSynchronizedAtMethodLevel"
language="java"
since="3.0"
message="Use block level rather than method level synchronization"
message="Use block level locking rather than method level synchronization"
class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#avoidsynchronizedatmethodlevel">
<description>
Method-level synchronization can cause problems when new code is added to the method.
Block-level synchronization helps to ensure that only the code that needs synchronization
gets it.
Method-level synchronization will pin virtual threads and can cause performance problems. Additionally, it can cause
problems when new code is added to the method. Block-level ReentrantLock helps to ensure that only the code that
needs mutual exclusion will be locked.
</description>
<priority>3</priority>
<properties>
@ -30,7 +30,7 @@ gets it.
<![CDATA[
public class Foo {
// Try to avoid this:
synchronized void foo() {
synchronized void bar() {
// code, that doesn't need synchronization
// ...
// code, that requires synchronization
@ -41,13 +41,18 @@ public class Foo {
// ...
}
// Prefer this:
Lock instanceLock = new ReentrantLock();
void bar() {
// code, that doesn't need synchronization
// ...
synchronized(this) {
try {
instanceLock.lock(); // or instanceLock.tryLock(long time, TimeUnit unit)
if (!sharedData.has("bar")) {
sharedData.add("bar");
}
} finally {
instanceLock.unlock();
}
// more code, that doesn't need synchronization
// ...
@ -58,11 +63,16 @@ public class Foo {
}
// Prefer this:
private static Lock CLS_LOCK = new ReentrantLock();
static void barStatic() {
// code, that doesn't need synchronization
// ...
synchronized(Foo.class) {
try {
CLS_LOCK.lock();
// code, that requires synchronization
} finally {
CLS_LOCK.unlock();
}
// more code, that doesn't need synchronization
// ...
@ -72,6 +82,50 @@ public class Foo {
</example>
</rule>
<rule name="AvoidSynchronizedStatement"
language="java"
since="7.5.0"
message="Use ReentrantLock rather than synchronization"
class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#avoidsynchronizedstatement">
<description>
Synchronization will pin virtual threads and can cause performance problems.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>//SynchronizedStatement</value>
</property>
</properties>
<example>
<![CDATA[
public class Foo {
// Try to avoid this:
void foo() {
// code that doesn't need mutual exclusion
synchronized(this) {
// code that requires mutual exclusion
}
// more code that doesn't need mutual exclusion
}
// Prefer this:
Lock instanceLock = new ReentrantLock();
void foo() {
// code that doesn't need mutual exclusion
try {
instanceLock.lock(); // or instanceLock.tryLock(long time, TimeUnit unit)
// code that requires mutual exclusion
} finally {
instanceLock.unlock();
}
// more code that doesn't need mutual exclusion
}
}
]]>
</example>
</rule>
<rule name="AvoidThreadGroup"
language="java"
since="3.6"