Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: REM cost reform

Overriding thread-safe methods with methods that are not thread-safe unsafe for concurrent use can result in improper synchronization, if the client when a client that depends on the thread-safety promised by the parent inadvertently operates on an instance of the subclass. An For example, an overridden synchronized method's contract can be violated , if when a subclass provides an implementation that is not safe unsafe for concurrent use. Overriding thread-safe methods with methods that are not thread-safe is not, in itself, an error. However, it is disallowed by this rule, because it may Such overriding can easily result in errors that are difficult to diagnose. Consequently, programs must not override thread-safe methods with methods that are unsafe for concurrent use.

The locking strategy of classes designed for inheritance should always be documented. This information can subsequently be used to determine an appropriate locking strategy for subclasses (see rule LCK00-J. Use private final lock objects to synchronize classes that may interact with untrusted code and LCK11-J. Avoid client-side locking when using classes that do not commit to their locking strategy).

Noncompliant Code Example (Synchronized Method)

This noncompliant code example overrides the synchronized doSomething() method in the Base class with an unsynchronized method in the Derived class.:

Code Block
bgColor#FFCCCC

class Base {
  public synchronized void doSomething() {
    // ...
  }
}

class Derived extends Base {
  @Override public void doSomething() {
    // ...
  }
}

...

This programming error can be difficult to diagnose , because threads that accept instances of Base can also accept instances of its subclasses. Consequently, clients could be unaware that they are operating on an a thread-unsafe instance of the a subclass of a thread-safe class that is not thread-safe.

Compliant Solution (Synchronized Method)

This compliant solution synchronizes the doSomething() method of the subclass.:

Code Block
bgColor#ccccff

class Base {
  public synchronized void doSomething() {
    // ...
  }
}

class Derived extends Base {
  @Override public synchronized void doSomething() {
    // ...
  }
}

This compliant solution does not violate rule solution also complies with LCK00-J. Use private final lock objects to synchronize classes that may interact with untrusted code because the accessibility of the class is package-private. That type of Package-private accessibility is allowable permitted when untrusted code cannot infiltrate the package.

...

This compliant solution ensures that the Derived class is is thread-safe by overriding the synchronized doSomething() method of the Base class with a method that synchronizes on a private final lock object.

Code Block
bgColor#ccccff

class Base {

  public synchronized void doSomething() {
    // ...
  }
}

class Derived extends Base {
  private final Object lock = new Object();

  @Override public void doSomething() {
    synchronized (lock) {
      // ...
    }
  }
}

This is an acceptable solution, provided the locking policy of the Derived class has a consistent locking policyis consistent with that of the Base class.

Noncompliant Code Example (Private Lock)

This noncompliant code example defines a doSomething() method in the Base class that uses a private final lock , in accordance with rule LCK00-J. Use private final lock objects to synchronize classes that may interact with untrusted code.

Code Block
bgColor#FFCCCC

class Base {
  private final Object lock = new Object();

  public void doSomething() {
    synchronized (lock) {
      // ...
    }
  }
}

class Derived extends Base {
  Logger logger = // Initialize

  @Override public void doSomething() {
    try {
      super.doSomething();
    } finally {
      logger.log(Level.FINE, "Did something");
    }
  }
}

It is possible for multiple threads to cause the entries to be logged in an order that differs from the order in which the tasks are performed. Consequently, the doSomething() method of the Derived class cannot be used safely by multiple threads because it is not thread-safe.

Compliant Solution (Private Lock)

This compliant solution solution synchronizes the doSomething() method of the subclass using a its own private final lock object.:

Code Block
bgColor#ccccff

class Base {
  private final Object lock = new Object();

  public void doSomething() {
    synchronized (lock) {
      // ...
    }
  }
}

class Derived extends Base {
  Logger logger = // Initialize

  private final Object lock = new Object();

  @Override public void doSomething() {
    synchronized (lock) {
      try {
        super.doSomething();
      } finally {
        logger.log(Level.FINE, "Did something");
      }
    }
  }
}

Note that the Base and Derived objects maintain distinct locks that are inaccessible from each othersother's classes. Consequently, Derived can provide thread-safety guarantees independent of Base.

Risk Assessment

Overriding Overriding thread-safe methods with methods that are not thread-safe unsafe for concurrent access can result in unexpected behavior.

Rule

Severity

Likelihood

Remediation Cost

Detectable

Repairable

Priority

Level

TSM00-J

Low

low

Probable

probable

Yes

medium

No

P4

L3

Automated Detection

...

Sound automated detection is infeasible; heuristic checks could be useful.

ToolVersionCheckerDescription
Parasoft Jtest

Include Page
Parasoft_V
Parasoft_V

CERT.TSM00.OSNSAvoid overriding synchronized methods with non-synchronized methods

Bibliography


...

Image Added Image Added Image Added

TODO

Related Vulnerabilities

Any vulnerabilities resulting from the violation of this rule are listed on the CERT website.

References

Wiki Markup
\[[API 2006|AA. Bibliography#API 06]\]
\[[SDN 2008|AA. Bibliography#SDN 08]\] Sun bug database, [Bug ID 4294756|http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4294756]

11. Thread-Safety Miscellaneous (TSM)      11. Thread-Safety Miscellaneous (TSM)      TSM01-J. Do not let the (this) reference escape during object construction