"When do these objects require external synchronization?"
"Which lock is needed for which operations?"
Here, "operations" on an object might come in two flavours:
The goal of this scheme is simply to tell the caller when they need to obtain an external lock before performing an operation in a multithreaded environment.
lock-never - the caller never needs to obtain an external lock before performing any operation of any kind. The class may be immutable, or it may perform all necessary synchronization internally. From the point of view of the caller, these two cases are functionally the same (in the context of documenting thread-safety).
lock-always - the caller always needs to obtain an external lock before performing any operation. Instances are mutable, and the implementation of the class performs no internal synchronization.
lock-sometimes - the caller sometimes needs to obtain a lock externally before performing some operations. Instances are mutable, and the implementation of the class performs most synchronization internally. The caller usually doesn't need to obtain an external lock, but there are some operations in which the caller does indeed need to obtain an external lock. The classic example of this is iteration over a collection.
lock-hostile - operations cannot be performed safely in a multi-threaded environment at all, even when an external lock is always obtained. This is a rare pathological case. It usually occurs when static data is modified without proper synchronization.
In practice, lock-always
and lock-never
are likely the most common cases.
To help you with documenting thread-safety, you might consider using:
-tag
option, which lets you define simple custom javadoc tags
Another reasonable option is to state in the javadoc overview that, unless stated otherwise, a class is to be considered lock-always
.