Java Reference
In-Depth Information
As of this writing, FindBugs includes detectors for the following concurrencyrelated bug pat-
terns, and more are being added all the time:
Inconsistent synchronization.
Many objects follow the synchronization policy of guard-
ing all variables with the object's intrinsic lock. If a field is accessed frequently but
not always with the
this
lock held, this may indicate that the synchronization policy
is not being consistently followed.
Analysis tools must guess at the synchronization policy because Java classes do not have
formal concurrency specifications. In the future, if annotations such as
@GuardedBy
are
standardized, auditing tools could interpret annotations rather than having to guess at the re-
lationship between variables and locks, thus improving the quality of analysis.
Invoking
Thread.run
.
Thread
implements
Runnable
and therefore has a
run
method. However, it is almost always a mistake to call
Thread.run
directly; usu-
ally the programmer meant to call
Thread.start
.
Unreleased lock.
Unlike intrinsic locks, explicit locks (see
Chapter 13
)
are not automatic-
ally released when control exits the scope in which they were acquired. The standard
idiom is to release the lock from a
finally
block; otherwise the lock can remain
unreleased in the event of an
Exception
.
Empty
synchronized
block.
While empty
synchronized
blocks do have se-
mantics under the Java Memory Model, they are frequently used incorrectly, and there
are usually better solutions to whatever problem the developer was trying to solve.
Double-checked locking.
Double-checked locking is a broken idiom for reducing syn-
chronization overhead in lazy initialization (see
Section 16.2.4
)
that involves reading
a shared mutable field without appropriate synchronization.
Starting a thread from a constructor.
Starting a thread from a constructor introduces the
risk of subclassing problems, and can allow the
this
reference to escape the con-
structor.
Notification errors.
The
notify
and
notifyAll
methods indicate that an object's state
may have changed in a way that would unblock threads that are waiting on the associ-
ated condition queue. These methods should be called only when the state associated
with the condition queue has changed. A
synchronized
block that calls
notify