The Java language facility for the annotation can be is useful for the documentation documenting programmer design intent about the concurrency properties of code. Annotation is a mechanism for associating a meta-tag with a program element and allowing the compiler, tools, or the VM to examine it. Several annotations are available to help with the documentation of thread-safety, or the lack thereof, of Java code.
Obtaining
...
Concurrency Annotations
Wiki Markup |
---|
There are two sets of concurrency annotations that are freely available and licensed for use in any code. The first is the four annotations described in _Java Concurrency in Practice_ (JCIP hereafter) \[[Goetz 06|AA. Java References#Goetz 06]\] which can be downloaded from [jcip.net|http://www.jcip.net] ([jar|http://jcip.net/jcip-annotations.jar], [javadoc|http://jcip.net/annotations/doc/index.html], [source|http://jcip.net/jcip-annotations-src.jar]). The JCIP annotations are released under the [Creative Commons Attribution License|http://creativecommons.org/licenses/by/2.5]. |
The second, larger, set of concurrency annotations is available from and supported by SureLogic. The SureLogic annotations are released under the The Apache Software License, Version 2.0 and can be downloaded from surelogic.com (jar, javadoc, source). These annotations can be verified by the SureLogic JSure tool but are useful for code documentation purposes without the tool. The SureLogic annotations include the JCIP annotations because they are also supported by the JSure tool (the tool also supports use of the JCIP Jar directly as well).
To use the annotations you , download and add one or both of the above Jar files to your code's build path. The use of these annotations to document thread-safety is sketched described below.
Documenting
...
Intended Thread-safety
JCIP provides three class-level annotations to describe the programmer's design intent with respect to thread-safety. In this section we describe these annotations and provide examples of their use (much of the material below is also in the Javadoc for the annotations.)
...
Example: The Aircraft class declares that it is thread-safe as part of its lock policy documentation. This class protects the x
and y
fields using a ReentrantLock
. The @Region and @RegionLock annotations (described below) document the precise locking policy that the promise of thread-safety is based upon.
Code Block | ||
---|---|---|
| ||
@ThreadSafe @Region("private AircraftState") @RegionLock("StateLock is stateLock protects AircraftState") public class Aircraft { private final Lock stateLock = new ReentrantLock(); ... @InRegion("AircraftState") private long x, y; ... public void setPosition(long x, long y) { stateLock.lock(); try { this.x = x; this.y = y; } finally { stateLock.unlock(); } } ... } |
...
Example: The immutable Point
class below is considered thread-safe.
Code Block | ||
---|---|---|
| ||
@Immutable public class Point { final int f_x; 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; } } |
...
Example: Most of the collection implementations provided in java.util
are not thread-safe. This could be documented for java.util.ArrayList
, for example, as shown below.
Code Block | ||
---|---|---|
| ||
package java.util; @NotThreadSafe public class ArrayList extends ... { ... } |
...
Typically, object construction is considered an exception to the locking policy. Why? This is because objects are thread-confined when they are constructed. They are confined to the thread that invoked the new
expression to construct the object. Subsequently, the object is safely published to other threads. At issue, is that the object does not become shared until the thread that invoked the new
expression expects it to. One approach is discussed in CON14-J. Do not let the "this" reference escape during object construction and can be expressed with the @Unique("return") annotation.
Code Block | ||
---|---|---|
| ||
@RegionLock("Lock is this protects Instance") public class Example { int x = 1; int y; @Unique("return") public Example(int y) { this.y = y; } ... } |
...