com.surelogic
Annotation Type ThreadSafe


@Documented
@Target(value=TYPE)
public @interface ThreadSafe

The type to which this annotation is applied is thread-safe. This means that no sequences of accesses (reads and writes to public fields, calls to public methods) may put the object into an invalid state, regardless of the interleaving of those actions by the runtime, and without requiring any additional synchronization or coordination on the part of the caller. Even if one or more RegionLock models has been developed to document the locking policy of a class this annotation can help to clarify that the overall class is thread-safe.

This annotation does not imply that a sequence made up of calls to methods of this class or accesses to fields of this class are atomic. It is a the responsibility of the caller to insure that such sequences execute atomically.

This annotation is currently verified, but not defined, by restricting how the fields of the class are declared and annotated. This is a conservative, although easily understood, way to verify the ThreadSafe assertion. Specifically, for a class annotated as @ThreadSafe to be verified, each field must be either

Where, by "safe" we mean that one of the following conditions is true:

Immutable objects are inherently thread-safe; they may be passed between threads or published without synchronization. Therefore instances of an Immutable type are also ThreadSafe, but not necessarily visa versa.

Typically, subtypes of the annotated type must be explicitly annotated @ThreadSafe or (the more restrictive, but also thread-safe) @Immutable. It is a modeling error if they are not. This annotation has two attributes, implementationOnly and verify, that control how subtypes of an ThreadSafe type must be annotated. The implementationOnly attribute indicates that the implementation of the annotated class should be assured without making a general statement about the visible behavior of the type or its subtypes. There are several rules with regards to the implementationOnly attribute on ThreadSafe types:

  1. The implementationOnly attribute must be false when ThreadSafe appears on an interface, because interfaces do not have an implementation.
  2. The subinterfaces of an interface annotated with ThreadSafe must be annotated with ThreadSafe; classes that implement an interface annotated with ThreadSafe must be annotated with @ThreadSafe(implementationOnly=false).
  3. The superclass of a class annotated with @ThreadSafe(implementationOnly=true) must be annotated with @ThreadSafe(implementationOnly=true); there are no constraints on the subclasses.
  4. The superclass of a class annotated with @ThreadSafe(implementationOnly=false) must be annotated with either @ThreadSafe(implementationOnly=false) or @ThreadSafe(implementationOnly=true); the subclasses must be annotated with @ThreadSafe(implementationOnly=false).
Finally, it may be possible to implement a class that satisfies the semantics of ThreadSafe, but that is not verifiable using the syntactic and annotation constraints described above. For this case, we provide the "escape hatch" of turning off tool verification for the annotation with the verify attribute. For example, @ThreadSafe(verify=false) would skip tool verification entirely.

A type may not be annotated with both @ThreadSafe and @NotThreadSafe.

Relationship with @Immutable

Thread safety and immutability are two points along the same axis. This set of annotations can actually describe three points along the axis:

@Mutable and @NotThreadSafe
This is the same as being unannotated, or just @Mutable, or just @NotThreadSafe. The type contains mutable state that is not safe to access concurrently from multiple threads.
@Mutable and @ThreadSafe
This is the same as @ThreadSafe. The type contains mutable state that is safe to access concurrently from multiple threads.
@Immutable and @ThreadSafe
This is the same as @Immutable. The type contains no mutable state, and is thus safe to access concurrently from multiple threads.

The combination @Immutable and @NotThreadSafe is a modeling error because an immutable type is obviously thread safe.

An @Immutable interface may extend a @ThreadSafe interface. An @Immutable class may implement a @ThreadSafe interface.

A @ThreadSafe class may extend a class annotated with @Immutable(implementationOnly=true).

Semantics:

All accesses to a non-final, non-volatile region of an instance of the annotated class occur either when Further, this assertion imposes that all the state referenced by instances of the annotated class, transitively, be likewise protected.

Examples:

The Point class is thread-safe because its fields are final and of primitive type.
 @ThreadSafe
 @Containable
 public class Point {
   private final int x;
 
   private final int y;
 
   @Unique("return")
   @RegionEffects("none")
   public Point(int x, int y) {
     this.x = x;
     this.y = y;
   }
 
   @Borrowed("this")
   @RegionEffects("none")
   @Unique("return")
   public Point translate(int dx, int dy) {
     return new Point(x + dx, y + dy);
   }
 }
 

The Rectangle class is thread-safe because its fields are final and of a type annotated @ThreadSafe:

 @ThreadSafe
 @Containable
 public class Rectangle {
   @Unique
   private final Point topLeft;
 
   @Unique
   private final Point bottomRight;
 
   @Unique("return")
   @RegionEffects("none")
   public Rectangle(@Unique Point a, @Unique Point b) {
     topLeft = a;
     bottomRight = b;
   }
 
   @Borrowed("this")
   @RegionEffects("none")
   @Unique("return")
   public Rectangle translate(int dx, int dy) {
     return new Rectangle(topLeft.translate(dx, dy), bottomRight.translate(dx, dy));
   }
 }
 

Alternatively, we can create a mutable thread-safe Rectangle class by protecting the state with a lock, and aggregating a containable mutable, but not thread-safe, Point class:

 @Containable
 public class Point {
   private int x;
   private int y;
 
   @Unique("return")
   @RegionEffects("none")
   public Point(int x, int y) {
     this.x = x;
     this.y = y;
   }
 
   @Borrowed("this")
   @RegionEffects("writes Instance")
   public void translate(int dx, int dy) {
     x += dx;
     y += dy;
   }
 }
 
 @ThreadSafe
 @RegionLock("Lock is this protects Instance")
 public class Rectangle {
   @Unique
   private final Point topLeft;
 
   @Unique
   private final Point bottomRight;
 
   @Unique("return")
   public Rectangle(int x1, int y1, int x2, int y2) {
     topLeft = new Point(x1, y1);
     bottomRight = new Point(x2, y2);
   }
 
   @Borrowed("this")
   @RegionEffects("writes Instance")
   public synchronized void translate(int dx, int dy) {
     topLeft.translate(dx, dy);
     bottomRight.translate(dx, dy);
   }
 }
 

Javadoc usage notes:

This annotation may placed in Javadoc, which can be useful for Java 1.4 code which does not include language support for annotations, via the @annotate tag.
 /**
  * @annotate ThreadSafe
  * @annotate RegionLock("Lock is this protects Instance")
  */
 public class Rectangle {
   ...
 }
 
Implementation note: This annotation is derived from @ThreadSafe proposed by Brian Goetz and Tim Peierls in the book Java Concurrency in Practice (Addison-Wesley 2006) we have simply adapted it to have semantics as a promise. Further, the annotation in net.jcip.annotations may be used instead of this one with the same tool behavior. One difference between the two annotations is that the annotation in com.surelogic adds the implementationOnly and verify attributes—these attributes can not be changed from their default values if the the net.jcip.annotations annotation is used. Another difference is that the annotation in net.jcip.annotations has retention policy of RetentionPolicy.RUNTIME while the annotation in com.surelogic has a retention policy of RetentionPolicy.CLASS.

See Also:
Containable, Immutable, NotThreadSafe, Region, RegionLock, Vouch

Optional Element Summary
 boolean implementationOnly
          Indicates that the implementation of the annotated class should be assured without making a general statement about the visible behavior of the type or its subtypes.
 boolean verify
          Indicates whether or not tool verification should be attempted.
 

implementationOnly

public abstract boolean implementationOnly
Indicates that the implementation of the annotated class should be assured without making a general statement about the visible behavior of the type or its subtypes.

Returns:
true if only the annotated class should be assured without making a general statement about the visible behavior of the type or its subtypes, false otherwise. The default value for this attribute is false.
Default:
false

verify

public abstract boolean verify
Indicates whether or not tool verification should be attempted.

Returns:
true if the claim should be verified by a tool, such as SureLogic JSure, false otherwise. The default value for this attribute is true.
Default:
true


Copyright © 2011 Surelogic, Inc.. All Rights Reserved.