@Documented @Retention(value=SOURCE) @Target(value={CONSTRUCTOR,FIELD,METHOD,TYPE}) public @interface ThreadRestricted
The restriction applies to a field, constructor or method. It does not necessarily apply to any associated object that is read from the field, or created by the constructor, or returned by the method. The associated object's thread safety is normally documented by its own type API. However, if the type API documents no specific restriction, then the object assumes the restriction of the field, constructor or method whence it came. [See also @Warning("thread restricted object") and @Warning( "thread restricted elements")].
When applied to a type (class or interface), the ThreadRestricted annotation specifies the default restriction for all public methods. Any public method that lacks its own restriction is bound by the default. See the step-by-step rules for resolving the thread safety of public methods. Methods alone have such defaults, not fields or constructors.
The restriction may be to a particular thread. For instance, most Swing code is restricted to the AWT event dispatch thread. An appropriate annotation would be:
@ThreadRestricted("AWT event dispatch")
As well, a constructor or method might implement an internal, runtime test of compliance:
assert java.awt.EventQueue.isDispatchThread();
The thread may be specified as the constructor. In this case, access is restricted to the construction thread as though for purposes of construction. This means that access is forbidden even to the construction thread if another thread has already accessed an instance member.
@ThreadRestricted("constructor")
The restriction may specify a particular synchronization lock. For example:
@ThreadRestricted("holds Class.this") @ThreadRestricted("holds object") @ThreadRestricted("holds lock")
These specify that the thread must hold the monitor lock of the containing instance (this), or of some other object; or that it must hold a particular ReentrantLock. As well, a runtime test of compliance may be implemented within the restricted code:
assert Thread.holdsLock( Class.this ); assert Thread.holdsLock( object ); assert lock.isHeldByCurrentThread();
The restriction may specify that threads must touch-synchronize. For example:
@ThreadRestricted("touch") @ThreadRestricted("touch Class.this") @ThreadRestricted("touch object") @ThreadRestricted("touch lock")
These mean that access is thread-safe, but modifications to state variables are not guaranteed to be visible to other threads unless they touch-synchronize on a common lock. The method of touch-synchronizing depends on whether the thread is reading from state, or writing to it. If reading, the thread must grab the lock at some point before reading (thus ensuring that its local memory cache is invalidated). The thread need not continue to hold the lock while reading, but may release it beforehand.
If writing to state, the thread must release the lock at some point after writing (thus ensuring that its local memory cache is flushed). The thread need not actually hold the lock at time of writing, but may grab it and subsequently release it. Only after the lock is released are the state changes guaranteed to reach main memory, and become readable by other threads that touch-synchronize.
If the thread is both reading and writing, then it must do both: grab the lock before reading; and release it after writing. It need not hold onto the lock in the meantime, but may grab it and release it, once beforehand, and once afterwards.
If no particular lock is specified, then any lock (or locks) will suffice. Visibility is guaranteed only among those threads that touch-synchronize on the same lock.
The restriction may be left unspecified. This is the default value, so these are equivalent:
@ThreadRestricted @ThreadRestricted("unspecified")
This form of the annotation is generally applied at the type level. It defers the choice of restriction to the runtime code that constructs instances of the type. The code may choose either a single threaded or a locking restriction, and its choices may vary from instance to instance. In other words, the unpecified thread restriction simply means "not thread safe" and is handled accordingly.
ThreadSafe