...
Overriding thread-safe methods with methods that are not thread-safe is not, in itself, an error. However. , it is disallowed by this guideline, because it may easily result in errors that are difficult to diagnose.
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 guideline LCK00-J. Use private final lock objects to synchronize classes that may interact with untrusted code).
...
This noncompliant code example overrides the synchronized doSomething() method in the Base class with an unsynchronized method in the derived Derived class.
| Code Block | ||
|---|---|---|
| ||
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 instance of the subclass of a thread-safe class that is not in fact thread-safe.
Compliant Solution (Synchronized Method)
...
| Code Block | ||
|---|---|---|
| ||
class Base {
public synchronized void doSomething() {
// ...
}
}
class Derived extends Base {
@Override public synchronized void doSomething() {
// ...
}
}
|
This compliant solution does not violate guideline 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 accessibility is allowable when untrusted code cannot infiltrate the package.
...
| Code Block | ||
|---|---|---|
| ||
class Base {
public synchronized void doSomething() {
// ...
}
}
class Derived extends Base {
private final Object lock = new Object();
public void doSomething() {
synchronized (lock) {
// ...
}
}
}
|
...
This noncompliant code example defines a doSomething() method in the Base class that uses a private final lock, in accordance with guideline LCK00-J. Use private final lock objects to synchronize classes that may interact with untrusted code.
| Code Block | ||
|---|---|---|
| ||
class Base {
private final Object lock = new Object();
public void doSomething() {
synchronized (lock) {
// ...
}
}
}
class Derived extends Base {
@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.
...
| Code Block | ||
|---|---|---|
| ||
class Base {
private final Object lock = new Object();
public void doSomething() {
synchronized (lock) {
// ...
}
}
}
class Derived extends Base {
private final Object lock = new Object();
@Override public void doSomething() {
synchronized (lock) {
try {
super.doSomething();
} finally {
logger.log(Level.FINE, "Did something");
}
}
}
}
|
...
Overriding thread-safe methods with methods that are not thread-safe can result in unexpected behavior.
Rule Guideline | Severity | Likelihood | Remediation Cost | Priority | Level |
|---|---|---|---|---|---|
CON15 TSM00- J | low | probable | medium | P4 | L3 |
Automated Detection
...
References
| Wiki Markup |
|---|
\[[API 062006|AA. Java References#API 06]\] \[[SDN 082008|AA. Java References#SDN 08]\] Sun bug database, [Bug ID 4294756|http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4294756] |
...