48 * these methods may instead return the special value zero to
49 * represent failure to acquire access. Lock release and conversion
50 * methods require stamps as arguments, and fail if they do not match
51 * the state of the lock. The three modes are:
52 *
53 * <ul>
54 *
55 * <li><b>Writing.</b> Method {@link #writeLock} possibly blocks
56 * waiting for exclusive access, returning a stamp that can be used
57 * in method {@link #unlockWrite} to release the lock. Untimed and
58 * timed versions of {@code tryWriteLock} are also provided. When
59 * the lock is held in write mode, no read locks may be obtained,
60 * and all optimistic read validations will fail.
61 *
62 * <li><b>Reading.</b> Method {@link #readLock} possibly blocks
63 * waiting for non-exclusive access, returning a stamp that can be
64 * used in method {@link #unlockRead} to release the lock. Untimed
65 * and timed versions of {@code tryReadLock} are also provided.
66 *
67 * <li><b>Optimistic Reading.</b> Method {@link #tryOptimisticRead}
68 * returns a non-zero stamp only if the lock is not currently held
69 * in write mode. Method {@link #validate} returns true if the lock
70 * has not been acquired in write mode since obtaining a given
71 * stamp. This mode can be thought of as an extremely weak version
72 * of a read-lock, that can be broken by a writer at any time. The
73 * use of optimistic mode for short read-only code segments often
74 * reduces contention and improves throughput. However, its use is
75 * inherently fragile. Optimistic read sections should only read
76 * fields and hold them in local variables for later use after
77 * validation. Fields read while in optimistic mode may be wildly
78 * inconsistent, so usage applies only when you are familiar enough
79 * with data representations to check consistency and/or repeatedly
80 * invoke method {@code validate()}. For example, such steps are
81 * typically required when first reading an object or array
82 * reference, and then accessing one of its fields, elements or
83 * methods.
84 *
85 * </ul>
86 *
87 * <p>This class also supports methods that conditionally provide
88 * conversions across the three modes. For example, method {@link
89 * #tryConvertToWriteLock} attempts to "upgrade" a mode, returning
90 * a valid write stamp if (1) already in writing mode (2) in reading
91 * mode and there are no other readers or (3) in optimistic mode and
92 * the lock is available. The forms of these methods are designed to
93 * help reduce some of the code bloat that otherwise occurs in
94 * retry-based designs.
95 *
96 * <p>StampedLocks are designed for use as internal utilities in the
97 * development of thread-safe components. Their use relies on
98 * knowledge of the internal properties of the data, objects, and
99 * methods they are protecting. They are not reentrant, so locked
100 * bodies should not call other unknown methods that may try to
101 * re-acquire locks (although you may pass a stamp to other methods
102 * that can use or convert it). The use of read lock modes relies on
103 * the associated code sections being side-effect-free. Unvalidated
104 * optimistic read sections cannot call methods that are not known to
105 * tolerate potential inconsistencies. Stamps use finite
106 * representations, and are not cryptographically secure (i.e., a
107 * valid stamp may be guessable). Stamp values may recycle after (no
108 * sooner than) one year of continuous operation. A stamp held without
109 * use or validation for longer than this period may fail to validate
110 * correctly. StampedLocks are serializable, but always deserialize
111 * into initial unlocked state, so they are not useful for remote
112 * locking.
113 *
114 * <p>Like {@link java.util.concurrent.Semaphore Semaphore}, but unlike most
115 * {@link Lock} implementations, StampedLocks have no notion of ownership.
116 * Locks acquired in one thread can be released or converted in another.
117 *
118 * <p>The scheduling policy of StampedLock does not consistently
119 * prefer readers over writers or vice versa. All "try" methods are
120 * best-effort and do not necessarily conform to any scheduling or
121 * fairness policy. A zero return from any "try" method for acquiring
122 * or converting locks does not carry any information about the state
123 * of the lock; a subsequent invocation may succeed.
124 *
125 * <p>Because it supports coordinated usage across multiple lock
126 * modes, this class does not directly implement the {@link Lock} or
127 * {@link ReadWriteLock} interfaces. However, a StampedLock may be
128 * viewed {@link #asReadLock()}, {@link #asWriteLock()}, or {@link
129 * #asReadWriteLock()} in applications requiring only the associated
130 * set of functionality.
131 *
132 * <p><b>Sample Usage.</b> The following illustrates some usage idioms
133 * in a class that maintains simple two-dimensional points. The sample
134 * code illustrates some try/catch conventions even though they are
135 * not strictly needed here because no exceptions can occur in their
136 * bodies.
137 *
138 * <pre> {@code
139 * class Point {
140 * private double x, y;
141 * private final StampedLock sl = new StampedLock();
142 *
143 * // an exclusively locked method
144 * void move(double deltaX, double deltaY) {
145 * long stamp = sl.writeLock();
146 * try {
147 * x += deltaX;
148 * y += deltaY;
149 * } finally {
150 * sl.unlockWrite(stamp);
|
48 * these methods may instead return the special value zero to
49 * represent failure to acquire access. Lock release and conversion
50 * methods require stamps as arguments, and fail if they do not match
51 * the state of the lock. The three modes are:
52 *
53 * <ul>
54 *
55 * <li><b>Writing.</b> Method {@link #writeLock} possibly blocks
56 * waiting for exclusive access, returning a stamp that can be used
57 * in method {@link #unlockWrite} to release the lock. Untimed and
58 * timed versions of {@code tryWriteLock} are also provided. When
59 * the lock is held in write mode, no read locks may be obtained,
60 * and all optimistic read validations will fail.
61 *
62 * <li><b>Reading.</b> Method {@link #readLock} possibly blocks
63 * waiting for non-exclusive access, returning a stamp that can be
64 * used in method {@link #unlockRead} to release the lock. Untimed
65 * and timed versions of {@code tryReadLock} are also provided.
66 *
67 * <li><b>Optimistic Reading.</b> Method {@link #tryOptimisticRead}
68 * returns a non-zero stamp only if the lock is not currently held in
69 * write mode. Method {@link #validate} returns true if the lock has not
70 * been acquired in write mode since obtaining a given stamp, in which
71 * case all actions prior to the most recent write lock release
72 * happen-before actions following the call to {@code tryOptimisticRead}.
73 * This mode can be thought of as an extremely weak version of a
74 * read-lock, that can be broken by a writer at any time. The use of
75 * optimistic read mode for short read-only code segments often reduces
76 * contention and improves throughput. However, its use is inherently
77 * fragile. Optimistic read sections should only read fields and hold
78 * them in local variables for later use after validation. Fields read
79 * while in optimistic read mode may be wildly inconsistent, so usage
80 * applies only when you are familiar enough with data representations to
81 * check consistency and/or repeatedly invoke method {@code validate()}.
82 * For example, such steps are typically required when first reading an
83 * object or array reference, and then accessing one of its fields,
84 * elements or methods.
85 *
86 * </ul>
87 *
88 * <p>This class also supports methods that conditionally provide
89 * conversions across the three modes. For example, method {@link
90 * #tryConvertToWriteLock} attempts to "upgrade" a mode, returning
91 * a valid write stamp if (1) already in writing mode (2) in reading
92 * mode and there are no other readers or (3) in optimistic read mode
93 * and the lock is available. The forms of these methods are designed to
94 * help reduce some of the code bloat that otherwise occurs in
95 * retry-based designs.
96 *
97 * <p>StampedLocks are designed for use as internal utilities in the
98 * development of thread-safe components. Their use relies on
99 * knowledge of the internal properties of the data, objects, and
100 * methods they are protecting. They are not reentrant, so locked
101 * bodies should not call other unknown methods that may try to
102 * re-acquire locks (although you may pass a stamp to other methods
103 * that can use or convert it). The use of read lock modes relies on
104 * the associated code sections being side-effect-free. Unvalidated
105 * optimistic read sections cannot call methods that are not known to
106 * tolerate potential inconsistencies. Stamps use finite
107 * representations, and are not cryptographically secure (i.e., a
108 * valid stamp may be guessable). Stamp values may recycle after (no
109 * sooner than) one year of continuous operation. A stamp held without
110 * use or validation for longer than this period may fail to validate
111 * correctly. StampedLocks are serializable, but always deserialize
112 * into initial unlocked state, so they are not useful for remote
113 * locking.
114 *
115 * <p>Like {@link java.util.concurrent.Semaphore Semaphore}, but unlike most
116 * {@link Lock} implementations, StampedLocks have no notion of ownership.
117 * Locks acquired in one thread can be released or converted in another.
118 *
119 * <p>The scheduling policy of StampedLock does not consistently
120 * prefer readers over writers or vice versa. All "try" methods are
121 * best-effort and do not necessarily conform to any scheduling or
122 * fairness policy. A zero return from any "try" method for acquiring
123 * or converting locks does not carry any information about the state
124 * of the lock; a subsequent invocation may succeed.
125 *
126 * <p>Because it supports coordinated usage across multiple lock
127 * modes, this class does not directly implement the {@link Lock} or
128 * {@link ReadWriteLock} interfaces. However, a StampedLock may be
129 * viewed {@link #asReadLock()}, {@link #asWriteLock()}, or {@link
130 * #asReadWriteLock()} in applications requiring only the associated
131 * set of functionality.
132 *
133 * <p><b>Memory Synchronization.</b> Methods with the effect of
134 * successfully locking in any mode have the same memory
135 * synchronization effects as a <em>Lock</em> action described in
136 * <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.4">
137 * Chapter 17 of <cite>The Java™ Language Specification</cite></a>.
138 * Methods successfully unlocking in write mode have the same memory
139 * synchronization effects as an <em>Unlock</em> action. In optimistic
140 * read usages, actions prior to the most recent write mode unlock action
141 * are guaranteed to happen-before those following a tryOptimisticRead
142 * only if a later validate returns true; otherwise there is no guarantee
143 * that the reads between tryOptimisticRead and validate obtain a
144 * consistent snapshot.
145 *
146 * <p><b>Sample Usage.</b> The following illustrates some usage idioms
147 * in a class that maintains simple two-dimensional points. The sample
148 * code illustrates some try/catch conventions even though they are
149 * not strictly needed here because no exceptions can occur in their
150 * bodies.
151 *
152 * <pre> {@code
153 * class Point {
154 * private double x, y;
155 * private final StampedLock sl = new StampedLock();
156 *
157 * // an exclusively locked method
158 * void move(double deltaX, double deltaY) {
159 * long stamp = sl.writeLock();
160 * try {
161 * x += deltaX;
162 * y += deltaY;
163 * } finally {
164 * sl.unlockWrite(stamp);
|