Java Reference
In-Depth Information
Each use of synchronized , volatile , or any thread-safe class reflects a synchroniz-
ation policy defining a strategy for ensuring the integrity of data in the face of concurrent
access. That policy is an element of your program's design, and should be documented. Of
course, the best time to document design decisions is at design time. Weeks or months later,
the details may be a blur—so write it down before you forget.
Crafting a synchronization policy requires a number of decisions: which variables to make
volatile , which variables to guard with locks, which lock(s) guard which variables, which
variables to make immutable or confine to a thread, which operations must be atomic, etc.
Some of these are strictly implementation details and should be documented for the sake of
future maintainers, but some affect the publicly observable locking behavior of your class
and should be documented as part of its specification.
At the very least, document the thread safety guarantees made by a class. Is it thread-safe?
Does it make callbacks with a lock held? Are there any specific locks that affect its beha-
vior? Don't force clients to make risky guesses. If you don't want to commit to supporting
client-side locking, that's fine, but say so. If you want clients to be able to create new atomic
operations on your class, as we did in Section 4.4 , you need to document which locks they
should acquire to do so safely. If you use locks to guard state, document this for future main-
tainers, because it's so easy—the @GuardedBy annotation will do the trick. If you use more
subtle means to maintain thread safety, document them because they may not be obvious to
maintainers.
The current state of affairs in thread safety documentation, even in the platform library
classes, is not encouraging. How many times have you looked at the Javadoc for a class and
wondered whether it was thread-safe? [8] Most classes don't offer any clue either way. Many
official Java technology specifications, such as servlets and JDBC, woefully underdocument
their thread safety promises and requirements.
While prudence suggests that we not assume behaviors that aren't part of the specification,
we have work to get done, and we are often faced with a choice of bad assumptions. Should
we assume an object is thread-safe because it seems that it ought to be? Should we assume
that access to an object can be made thread-safe by acquiring its lock first? (This risky tech-
nique works only if we control all the code that accesses that object; otherwise, it provides
only the illusion of thread safety.) Neither choice is very satisfying.
Search WWH ::




Custom Search