Annotations
The annotations package contains variations or implementations of Brian Goetz and Tim Peierls' Concurrency In Practice annotations as well as some additional annotations useful when writing concurrent code.
@Concurrent
The Concurrent annotation is fully documented in the concurrency section and offers a way to either document a method as potentially being run from a concurrent context or combined with a ConcurrentRule or ConcurrentTestRunner, mark a JUnit test to run in parallel.
@Immutable
The Immutable annotation offers a way to document the intent that a class should be immutable.
Although potentially difficult to implement fully, this can be combined with AOP to try and enforce immutability. An example of a partially implemented AspectJ aspect is provided with tempus-fugit and reproduced here.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
Note that the example above doesn't ensure that all members are themselves Immutable or that constructors / accessors against collections ensure immutability. It also doesn't support junit tests that do not extend TestCase.
@Intermittent
The Intermittent annotation is fully documented in the concurrency section and offers a way to indicate tests intermittently fail. If you're using JUnit, you can also re-run the tests several times using the IntermittentTestRunner classes.
@Not
The Not annotation can be used to explicitly document the intent to not another annotation. For example, to document that some class is not thread- safe and doesn't and should not be immutable (ie, it's intentionally mutable), you could write
1 2 3 4 | |
You can supply as many arguments as you like as long as they make sense to you.
@Repeating
The Repeating annotation is documented in the concurrency section and offers a mechanism to repeatedly run a test method for load or soak test purposes. It can be combined with the Concurrent annotation to run test methods multiple times across multiple threads.
@Task
The Task annotation is intended to document that a class is a concurrent task. A vanilla Runnable or Callable implementation for example may be used to implement some general purpose piece of functionality. Often, these will represent small tasks to be executed in serial, by annotating it as a task, you convey that the intended usage is from a concurrent context. For example, the Runnable will be run in parallel with other tasks.
Most concurrent applications are organised around the execution of tasks: abstract, discrete units of work. Dividing the work of an application into tasks simplifies organisation, facilitates error recovering by providing natural transaction boundaries, and promotes concurrency by providing a natural structure for paralleslising work.
With this annotation, when we talk about tasks we really mean concurrent tasks.
@ThreadSafe
The ThreadSafe annotation is a direct implementation of the Goetz version. It is used to document that the author thinks a class is thread safe.
@GuardedBy
The GaurdedBy annotation is a variation on the Goetz version whereby the the lock and lock details are explicitly set as parameter types. See Concurrency In Practice for an in-depth description of it's use.
The enum GuardedBy.Type defines the following lock types based on the Goetz version.
THISINNER_CLASS_THISITSELFFIELDSTATIC_FIELDMETHOD
THIS
In the example below, shows how the THIS lock type is used. All access to the bar member is guarded by the instance monitor object off Foo.
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
INNER_CLASS_THIS
The INNER_CLASS_THIS type is a way of disambiguating from THIS when it's used from an inner class. However, it's marked as deprecated as THIS can still be used and disambiguated by using the details parameter. For example,
1 2 3 4 5 6 7 8 9 10 11 | |
ITSELF
It may be necessary to indicate that another object is responsible for its own synchronisation policy. For example, when avoiding ConcurrentModificationException on summing a list of numbers below, we declare our List using Collections.synchronizedList. Internally, this thread-safe list uses itself to guard access, we reflect this using the annotation as below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
FIELD and STATIC_FIELD
Using a field to synchronise access can be seen in the example below (based on an example from Goetz).
1 2 3 4 5 6 7 8 9 10 | |
METHOD
When a lock is obtained via some method, the METHOD type along with a details can be used. A trivial example is shown below. We haven't found much use for this type, but that's not to say that you won't
1 2 3 4 5 6 7 8 9 10 11 12 13 | |