package votorola.g.lang; // Copyright 2006-2009, 2013, Michael Allan. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Votorola Software"), to deal in the Votorola Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicence, and/or sell copies of the Votorola Software, and to permit persons to whom the Votorola Software is furnished to do so, subject to the following conditions: The preceding copyright notice and this permission notice shall be included in all copies or substantial portions of the Votorola Software. THE VOTOROLA SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE VOTOROLA SOFTWARE OR THE USE OR OTHER DEALINGS IN THE VOTOROLA SOFTWARE. import java.lang.annotation.*; /** Warns that access to a field, constructor or method is restricted to a particular * thread, or to a thread that holds a particular lock. The opposite of ThreadRestricted * is {@linkplain ThreadSafe ThreadSafe}. * *
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 @{@linkplain Warning * Warning}("thread restricted object") and @{@linkplain Warning 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 {@linkplain * java.util.concurrent.locks.ReentrantLock 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.
* * @see ThreadSafe */ @Documented @Retention(RetentionPolicy.SOURCE) // till further retention needed @Target({ ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD, ElementType.TYPE }) public @interface ThreadRestricted { /** Details of the thread restriction. */ public String value() default "unspecified"; }