Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: edits, first pass, please review

The Java language annotation facility for annotation is useful for documenting programmer the design intent about the behind specific concurrency properties of code. Annotation Source code annotation is a mechanism for associating a meta-tag metadata with a program element and allowing making it available to the compiler, tools such as debuggers, or the VM to examine itfor examination. Several annotations are available to help with the documentation of for documenting 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 isset consists theof 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 and are useful for documenting code documentation purposes without even if the tool is unavailable. The SureLogic annotations also include the JCIP annotations because they are also supported by the JSure tool (the tool JSure also supports use of the JCIP Jar directly as wellfile).

To use the annotations, download and add one or both of the above Jar files to your the code's build path. The use of these annotations to document thread-safety is described discussed below.

Documenting Intended Thread-safety

...

The @ThreadSafe annotation is applied to a class to indicate that the class it is thread-safe. This means that no sequences of accesses (reads and writes to public fields, calls to public methods) may put leave the object into in an invalid inconsistent state, regardless of the interleaving of those actions these accesses by the runtime , and without requiring or any additional synchronization or coordination on the part of the caller.

For example, the Aircraft class shown below declares that it is thread-safe as part of its lock policy documentation. This class protects the x and y fields using a ReentrantLock.

Code Block
bgColor#ccccff
 @ThreadSafe
 @Region("private AircraftState")
 @RegionLock("StateLock is stateLock protects AircraftState")
 public final 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();
     }
   }
   // ...
 }

The @Region and @RegionLock annotations (described below) document the precise locking policy that the promise of thread-safety is predicated upon.

Even if one or more @RegionLock or @GuardedBy annotations has have been made used to document the locking policy of a class this annotation can help to clarify that the overall , the @ThreadSafe annotation provides an intuitive way for reviewers to learn that the class is thread-safe.

@Immutable The class to which this : This annotation is applied is immutable. This means that its state cannot be seen to change by callers, which implies that (1) all public fields are final, (2) all public final reference fields refer to other immutable objects, and (3) constructors and methods do not publish references to any internal state which is potentially mutable by the implementation. Immutable objects may still have internal mutable state for purposes of performance optimization; some state variables may be lazily computed, provided they are computed from immutable state and that callers cannot tell the difference. Immutable objects are immutable classes. Immutable objects are inherently thread-safe; they may be passed between threads or published without synchronizationshared safely amongst multiple threads after they are fully constructed, and can be published by declaring the corresponding reference as volatile.

For example, the immutable Point class shown below is considered inherently thread-safe.

Code Block
bgColor#ccccff
 @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;
   }
 }

@NotThreadSafe The class to which this This annotation is applied is to classes that are not thread-safe. This annotation primarily exists for clarifying the non-thread-safety of a class that might otherwise be assumed to be thread-safe, despite the fact that it is a bad idea to assume a class is thread-safe without good reasonSeveral classes do not document whether they are safe for multithreaded use or not. Consequently, a programmer has no easy way to determine whether the class is thread-safe. This annotation provides clear indication of the class's lack of thread-safety.

For example, most of the collection implementations provided in java.util are not thread-safe. This could be documented for The class java.util.ArrayList, for example, which is not thread-safe could document this as shown below.

Code Block
bgColor#ccccff
 package java.util;
 
 @NotThreadSafe
 public class ArrayList extends ... {
   ...
 }

Documenting Lock Policies

Wiki Markup
OnAccording pageto 28Goetz ofet _Java Concurrency in Practice_ al. \[[Goetz 06, pg 28|AA. Java References#Goetz 06]\], Goetz states:

For each mutable state variable that may be accessed by more than one thread, all accesses to that variable must be preformed performed with the same lock headheld. In this case, we say that the variable is guarded by that lock.

ThereforeConsequently, it is important to document which lock is all the locks that are being used to protect each shared , mutable variablestate. JCIP provides the @GuardedBy annotation for this purpose while SureLogic provides the @RegionLock annotation. The use of both annotations is discussed in this section.

@GuardedBy: The field or method to which this annotation is applied can only be accessed when holding a particular lock, which may be a built-in (synchronization) an intrinsic lock, or may be an explicit a dynamic lock such as java.util.concurrent.Lock.

For example, the following MovablePoint class implements a movable point with a capability to remember (that is, memo) which has the capability of remembering its past locations using an array list, memo.

Code Block
bgColor#ccccff
@ThreadSafe
public final class MovablePoint {
 
  @GuardedBy("this") double xPos = 1.0;
  @GuardedBy("this") double yPos = 1.0;
  @GuardedBy("itself") static final ListList<MovablePoint> memo = new ArrayListArrayList<MovablePoint>();
 
  public void move(double slope, double distance) {
    rememberPoint(this);
    synchronized (this) {
      xPos += xPos + ((1 / slope) * distance);
      yPos += yPos + (slope * distance);
     }
  }

   public static void memorememberPoint(ex1MovablePoint 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 memo rememberPoint() method).

A problem with the @GuardedBy annotation is that it does not make it clear clarify that there is a relationship between the two fields in the example above. This limitation can be overcome by using the SureLogic @RegionLock which we now discuss annotation.

@RegionLock: Declares a new region lock for the class to which this annotation is applied. This declaration creates a new named lock that associates a particular lock object with a region of the class. The region may only be accessed when the lock is held.

For example, the SimpleLock locking policy indicates that synchronizing on the instance protects the all of the instance's state.

Code Block
bgColor#FFcccc#ccccff
 @RegionLock("SimpleLock is this protects Instance")
 class Simple { ... }

...

In addition to naming the locking policy, the @Region annotation allows a name to be given to the region of 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 examples below.

A locking policy, named StateLock, that indicates that locking on the java.util.concurrent.Lock stateLock protects the named region, AircraftPosition, that includes all of the mutable state used represent the position of the aircraft.

following example:

Code Block
bgColor#ccccff
 @Region("private AircraftPosition")
 @RegionLock("StateLock is stateLock protects AircraftPosition")
 public final class Aircraft {
   private final Lock stateLock = new ReentrantLock();

   @InRegion("AircraftPosition")
   private long x, y;

   @InRegion("AircraftPosition")
   private long altitude;
   // ...
   public void setPosition(long x, long y) {
     stateLock.lock();
     try {
       this.x = x;
       this.y = y;
     } finally {
       stateLock.unlock();
     }
   }
   // ...
 }

...

In this example, a locking policy named StateLock is used to indicate that locking on the java.util.concurrent.Lock stateLock protects the named region, AircraftPosition, which includes the mutable state used to represent the position of the aircraft.

Construction of mutable objects

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 uses the new expression operator to construct an instance of the object. Subsequently, the object is can be safely published to other threads. At issueHowever, is that the object does is not become shared until the thread that invoked the new expression expects it to. One approach is created the instance allows. Safe publication approaches discussed in CON14-J. Do not let the "this" reference escape during object construction and can be succinctly expressed with the @Unique("return") annotation.

For example, in the code shown below, the @Unique("return") annotation documents that the object returned from the constructor is a unique reference.

Code Block
bgColor#ccccff
 @RegionLock("Lock is this protects Instance")
 public final class Example {
 
  private int x = 1;
   private int y;
 
   @Unique("return")
   public Example(int y) {
     this.y = y;
   }
   // ...
 }

...

Documenting thread-confinement policies

Wiki Markup
Sutherland and
Scherlis in Composable Thread Coloring propose annotations that can document
 Scherlis \[[Sutherland 10|AA. Java References#Sutherland 10]\] propose annotations that can document thread-confinement policies. Their approach is designed to allow verification of the
annotations with the as written code
 annotations against code, as it exists.

For example, expression, using the annotations proposed by Sutherland and Scherlis, of to express the design intent that

  • a program has at most one AWT event dispatch thread,
  • as many Compute threads as it wishes and,

...

  • the Compute thread is forbidden to handle AWT data structures or events

use the following annotations:.

Code Block
bgColor#ccccff
@ColorDeclare AWT, Compute
@IncompatibleColors AWT, Compute
@MaxColorCount AWT 1

For more detail refer to the paper referenced above.

Documenting wait-notify protocols

...

Wait-notify protocols should be adequately documented. Currently, we are not aware of any annotations for this purpose.