...
For example, the Aircraft
class shown below declares specifies that it is thread-safe as part of its lock locking policy documentation. This class protects the x
and y
fields using a ReentrantLock
.
...
@Immutable: This annotation is applied to immutable classes. Immutable objects are inherently thread-safe; they may be safely shared safely amongst multiple threads after they are fully constructed, and can be published by declaring the corresponding reference as volatile.
For example, the The following example shows an immutable Point
class shown below is inherently thread-safe.:
Code Block | ||
---|---|---|
| ||
@Immutable public final class Point { private final int f_x; private final int f_y; public Point(int x, int y) { f_x = x; f_y = y; } public int getX() { return f_x; } public int getY() { return f_y; } } |
...
Code Block | ||
---|---|---|
| ||
package java.util; @NotThreadSafe public class ArrayList extends ... { ... } |
Documenting
...
Locking Policies
Wiki Markup |
---|
According to Goetz et al. \[[Goetz 06, pg 28|AA. Java References#Goetz 06]\]: |
...
Code Block | ||
---|---|---|
| ||
@ThreadSafe
public final class MovablePoint {
@GuardedBy("this") double xPos = 1.0;
@GuardedBy("this") double yPos = 1.0;
@GuardedBy("itself") static final List<MovablePoint> memo = new ArrayList<MovablePoint>();
public void move(double slope, double distance) {
rememberPoint(this);
synchronized (this) {
xPos += (1 / slope) * distance;
yPos += slope * distance;
}
}
public static void rememberPoint(MovablePoint value) {
synchronized (memo) {
memo.add(value);
}
}
}
|
The @GuardedBy annotations on the xPos
and yPos
fields indicate that access to these fields is protected by holding a lock on this
(as is done in the move()
method which mutates these fields). The @GuardedBy annotation on the memo
list indicates that a lock on the ArrayList
object protects its contents (as is done in the rememberPoint()
method).
A problem One issue with the @GuardedBy annotation is that it does not clarify that there is a relationship between the two fields in the above example above. This limitation can be overcome by using the SureLogic @RegionLock annotation.
...
For example, the SimpleLock
locking policy indicates that synchronizing on the instance protects all of the instance's state.:
Code Block | ||
---|---|---|
| ||
@RegionLock("SimpleLock is this protects Instance") class Simple { ... } |
Unlike the use of @GuardedBy, the @RegionLock annotation allows the program programmer to give an explicit, and hopefully meaningful, name to the locking policy.
In addition to naming the locking policy, the @Region annotation allows a name to be given to the region of the state that is being protected. This makes it clear that the state belongs together with respect to the locking policy. This is demonstrated in the following example:
...
Typically, object construction is considered an exception to the locking policy because objects are thread-confined when they are constructed. They are created. An object is confined to the thread that uses the new
operator to construct an instance of the object. Subsequentlycreate its instance. After creation, the object can be safely published to other threads. However, the object is not shared until the thread that created the instance allows. Safe publication approaches discussed in CON14-J. Do not let the "this" reference escape during object construction can be succinctly expressed with the @Unique("return") annotation.
...
For example, to express the design intent that a program has at most one AWT event dispatch thread,
...
several Compute threads
...
, and
...
the Compute
...
threads are forbidden to handle AWT data structures or events
...
, use the following annotations:
...