Rules that flag issues when dealing with multiple threads of execution.

AvoidSynchronizedAtMethodLevel

Since: PMD 3.0

Priority: Medium (3)

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.

This rule is defined by the following XPath expression:

//MethodDeclaration[@Synchronized = true()]

Example(s):

public class Foo {
    // Try to avoid this:
    synchronized void foo() {
        // code, that doesn't need synchronization
        // ...
        // code, that requires synchronization
        if (!sharedData.has("bar")) {
            sharedData.add("bar");
        }
        // more code, that doesn't need synchronization
        // ...
    }
    // Prefer this:
    void bar() {
        // code, that doesn't need synchronization
        // ...
        synchronized(this) {
            if (!sharedData.has("bar")) {
                sharedData.add("bar");
            }
        }
        // more code, that doesn't need synchronization
        // ...
    }

    // Try to avoid this for static methods:
    static synchronized void fooStatic() {
    }

    // Prefer this:
    static void barStatic() {
        // code, that doesn't need synchronization
        // ...
        synchronized(Foo.class) {
            // code, that requires synchronization
        }
        // more code, that doesn't need synchronization
        // ...
    }
}

Use this rule by referencing it:

<rule ref="category/java/multithreading.xml/AvoidSynchronizedAtMethodLevel" />

AvoidThreadGroup

Since: PMD 3.6

Priority: Medium (3)

Avoid using java.lang.ThreadGroup; although it is intended to be used in a threaded environment it contains methods that are not thread-safe.

This rule is defined by the following XPath expression:

//AllocationExpression/ClassOrInterfaceType[pmd-java:typeIs('java.lang.ThreadGroup')]|
//PrimarySuffix[contains(@Image, 'getThreadGroup')]

Example(s):

public class Bar {
    void buz() {
        ThreadGroup tg = new ThreadGroup("My threadgroup");
        tg = new ThreadGroup(tg, "my thread group");
        tg = Thread.currentThread().getThreadGroup();
        tg = System.getSecurityManager().getThreadGroup();
    }
}

Use this rule by referencing it:

<rule ref="category/java/multithreading.xml/AvoidThreadGroup" />

AvoidUsingVolatile

Since: PMD 4.1

Priority: Medium High (2)

Use of the keyword ‘volatile’ is generally used to fine tune a Java application, and therefore, requires a good expertise of the Java Memory Model. Moreover, its range of action is somewhat misknown. Therefore, the volatile keyword should not be used for maintenance purpose and portability.

This rule is defined by the following XPath expression:

//FieldDeclaration[@Volatile = true()]

Example(s):

public class ThrDeux {
  private volatile String var1; // not suggested
  private          String var2; // preferred
}

Use this rule by referencing it:

<rule ref="category/java/multithreading.xml/AvoidUsingVolatile" />

DoNotUseThreads

Since: PMD 4.1

Priority: Medium (3)

The J2EE specification explicitly forbids the use of threads. Threads are resources, that should be managed and monitored by the J2EE server. If the application creates threads on its own or uses own custom thread pools, then these threads are not managed, which could lead to resource exhaustion. Also, EJBs might be moved between machines in a cluster and only managed resources can be moved along.

This rule is defined by the following XPath expression:

//ClassOrInterfaceType[pmd-java:typeIs('java.lang.Thread') or pmd-java:typeIs('java.util.concurrent.ExecutorService')]
    (: exclude duplicated types on the same line :)
    [not((../../../../FieldDeclaration|../../../../LocalVariableDeclaration)/VariableDeclarator/VariableInitializer//AllocationExpression/ClassOrInterfaceType[pmd-java:typeIs('java.lang.Thread')])
     or
      @BeginLine != (../../../../FieldDeclaration|../../../../LocalVariableDeclaration)/VariableDeclarator/VariableInitializer//AllocationExpression/ClassOrInterfaceType[pmd-java:typeIs('java.lang.Thread')]/@BeginLine]
    (: exclude constructor call chains :)
    [not(parent::AllocationExpression/ClassOrInterfaceType[pmd-java:typeIs('java.lang.Thread')])]
|
//AllocationExpression/ClassOrInterfaceType[pmd-java:typeIs('java.lang.Thread')]
|
//StatementExpression/PrimaryExpression/PrimaryPrefix/Name[pmd-java:typeIs('java.util.concurrent.Executors') or pmd-java:typeIs('java.util.concurrent.ExecutorService')]

Example(s):

// This is not allowed
public class UsingThread extends Thread {

}

// Neither this,
public class UsingExecutorService {

    public void methodX() {
        ExecutorService executorService = Executors.newFixedThreadPool(5);
    }
}

// Nor this,
public class Example implements ExecutorService {

}

// Nor this,
public class Example extends AbstractExecutorService {

}

// Nor this
public class UsingExecutors {

    public void methodX() {
        Executors.newSingleThreadExecutor().submit(() -> System.out.println("Hello!"));
    }
}

Use this rule by referencing it:

<rule ref="category/java/multithreading.xml/DoNotUseThreads" />

DontCallThreadRun

Since: PMD 4.3

Priority: Medium Low (4)

Explicitly calling Thread.run() method will execute in the caller’s thread of control. Instead, call Thread.start() for the intended behavior.

This rule is defined by the following XPath expression:

//StatementExpression/PrimaryExpression
[
    PrimaryPrefix
    [pmd-java:typeIs('java.lang.Thread')]
    [
            ./Name[ends-with(@Image, '.run') or @Image = 'run']
        or
            ./AllocationExpression/ClassOrInterfaceType[pmd-java:typeIs('java.lang.Thread')]
            and ../PrimarySuffix[@Image = 'run']
    ]
]

Example(s):

Thread t = new Thread();
t.run();            // use t.start() instead
new Thread().run(); // same violation

Use this rule by referencing it:

<rule ref="category/java/multithreading.xml/DontCallThreadRun" />

DoubleCheckedLocking

Since: PMD 1.04

Priority: High (1)

Partially created objects can be returned by the Double Checked Locking pattern when used in Java. An optimizing JRE may assign a reference to the baz variable before it calls the constructor of the object the reference points to.

Note: With Java 5, you can make Double checked locking work, if you declare the variable to be volatile.

For more details refer to: http://www.javaworld.com/javaworld/jw-02-2001/jw-0209-double.html or http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html

This rule is defined by the following Java class: net.sourceforge.pmd.lang.java.rule.multithreading.DoubleCheckedLockingRule

Example(s):

public class Foo {
    /*volatile */ Object baz = null; // fix for Java5 and later: volatile
    Object bar() {
        if (baz == null) { // baz may be non-null yet not fully created
            synchronized(this) {
                if (baz == null) {
                    baz = new Object();
                }
              }
        }
        return baz;
    }
}

Use this rule by referencing it:

<rule ref="category/java/multithreading.xml/DoubleCheckedLocking" />

NonThreadSafeSingleton

Since: PMD 3.4

Priority: Medium (3)

Non-thread safe singletons can result in bad state changes. Eliminate static singletons if possible by instantiating the object directly. Static singletons are usually not needed as only a single instance exists anyway. Other possible fixes are to synchronize the entire method or to use an initialize-on-demand holder class.

Refrain from using the double-checked locking pattern. The Java Memory Model doesn’t guarantee it to work unless the variable is declared as volatile, adding an uneeded performance penalty. Reference

See Effective Java, item 48.

This rule is defined by the following Java class: net.sourceforge.pmd.lang.java.rule.multithreading.NonThreadSafeSingletonRule

Example(s):

private static Foo foo = null;

//multiple simultaneous callers may see partially initialized objects
public static Foo getFoo() {
    if (foo==null) {
        foo = new Foo();
    }
    return foo;
}

This rule has the following properties:

Name Default Value Description Multivalued
checkNonStaticMethods true Check for non-static methods. Do not set this to false and checkNonStaticFields to true. no
checkNonStaticFields false Check for non-static fields. Do not set this to true and checkNonStaticMethods to false. no

Use this rule with the default properties by just referencing it:

<rule ref="category/java/multithreading.xml/NonThreadSafeSingleton" />

Use this rule and customize it:

<rule ref="category/java/multithreading.xml/NonThreadSafeSingleton">
    <properties>
        <property name="checkNonStaticMethods" value="true" />
        <property name="checkNonStaticFields" value="false" />
    </properties>
</rule>

UnsynchronizedStaticDateFormatter

Deprecated

Since: PMD 3.6

Priority: Medium (3)

SimpleDateFormat instances are not synchronized. Sun recommends using separate format instances for each thread. If multiple threads must access a static formatter, the formatter must be synchronized on block level.

Note: This rule has been deprecated since PMD 6.11.0 and will be removed with PMD 7.0.0. The rule is replaced by the more general rule UnsynchronizedStaticFormatter.

This rule is defined by the following Java class: net.sourceforge.pmd.lang.java.rule.multithreading.UnsynchronizedStaticDateFormatterRule

Example(s):

public class Foo {
    private static final SimpleDateFormat sdf = new SimpleDateFormat();
    void bar() {
        sdf.format(); // poor, no thread-safety
    }
    void foo() {
        synchronized (sdf) { // preferred
            sdf.format();
        }
    }
}

This rule has the following properties:

Name Default Value Description Multivalued
allowMethodLevelSynchronization false If true, method level synchronization is allowed as well as synchronized block. Otherwise only synchronized blocks are allowed. no

Use this rule with the default properties by just referencing it:

<rule ref="category/java/multithreading.xml/UnsynchronizedStaticDateFormatter" />

Use this rule and customize it:

<rule ref="category/java/multithreading.xml/UnsynchronizedStaticDateFormatter">
    <properties>
        <property name="allowMethodLevelSynchronization" value="false" />
    </properties>
</rule>

UnsynchronizedStaticFormatter

Since: PMD 6.11.0

Priority: Medium (3)

Instances of java.text.Format are generally not synchronized. Sun recommends using separate format instances for each thread. If multiple threads must access a static formatter, the formatter must be synchronized on block level.

This rule is defined by the following Java class: net.sourceforge.pmd.lang.java.rule.multithreading.UnsynchronizedStaticFormatterRule

Example(s):

public class Foo {
    private static final SimpleDateFormat sdf = new SimpleDateFormat();
    void bar() {
        sdf.format(); // poor, no thread-safety
    }
    void foo() {
        synchronized (sdf) { // preferred
            sdf.format();
        }
    }
}

This rule has the following properties:

Name Default Value Description Multivalued
allowMethodLevelSynchronization false If true, method level synchronization is allowed as well as synchronized block. Otherwise only synchronized blocks are allowed. no

Use this rule with the default properties by just referencing it:

<rule ref="category/java/multithreading.xml/UnsynchronizedStaticFormatter" />

Use this rule and customize it:

<rule ref="category/java/multithreading.xml/UnsynchronizedStaticFormatter">
    <properties>
        <property name="allowMethodLevelSynchronization" value="false" />
    </properties>
</rule>

UseConcurrentHashMap

Since: PMD 4.2.6

Priority: Medium (3)

Minimum Language Version: Java 1.5

Since Java5 brought a new implementation of the Map designed for multi-threaded access, you can perform efficient map reads without blocking other threads.

This rule is defined by the following XPath expression:

//Type[../VariableDeclarator/VariableInitializer//AllocationExpression/ClassOrInterfaceType[@Image != 'ConcurrentHashMap']]
/ReferenceType/ClassOrInterfaceType[@Image = 'Map']

Example(s):

public class ConcurrentApp {
  public void getMyInstance() {
    Map map1 = new HashMap();           // fine for single-threaded access
    Map map2 = new ConcurrentHashMap(); // preferred for use with multiple threads

    // the following case will be ignored by this rule
    Map map3 = someModule.methodThatReturnMap(); // might be OK, if the returned map is already thread-safe
  }
}

Use this rule by referencing it:

<rule ref="category/java/multithreading.xml/UseConcurrentHashMap" />

UseNotifyAllInsteadOfNotify

Since: PMD 3.0

Priority: Medium (3)

Thread.notify() awakens a thread monitoring the object. If more than one thread is monitoring, then only one is chosen. The thread chosen is arbitrary; thus its usually safer to call notifyAll() instead.

This rule is defined by the following XPath expression:

//StatementExpression/PrimaryExpression
[PrimarySuffix/Arguments[@Size = 0]]
[
    PrimaryPrefix[
        ./Name[@Image='notify' or ends-with(@Image,'.notify')]
        or ../PrimarySuffix/@Image='notify'
        or (./AllocationExpression and ../PrimarySuffix[@Image='notify'])
    ]
]

Example(s):

void bar() {
    x.notify();
    // If many threads are monitoring x, only one (and you won't know which) will be notified.
    // use instead:
    x.notifyAll();
  }

Use this rule by referencing it:

<rule ref="category/java/multithreading.xml/UseNotifyAllInsteadOfNotify" />