20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 */
24
25 /*
26 * This file is available under and governed by the GNU General Public
27 * License version 2 only, as published by the Free Software Foundation.
28 * However, the following notice accompanied the original version of this
29 * file:
30 *
31 * Written by Doug Lea with assistance from members of JCP JSR-166
32 * Expert Group and released to the public domain, as explained at
33 * http://creativecommons.org/publicdomain/zero/1.0/
34 */
35
36 package java.util.concurrent.locks;
37
38 import java.util.Collection;
39 import java.util.concurrent.TimeUnit;
40
41 /**
42 * A reentrant mutual exclusion {@link Lock} with the same basic
43 * behavior and semantics as the implicit monitor lock accessed using
44 * {@code synchronized} methods and statements, but with extended
45 * capabilities.
46 *
47 * <p>A {@code ReentrantLock} is <em>owned</em> by the thread last
48 * successfully locking, but not yet unlocking it. A thread invoking
49 * {@code lock} will return, successfully acquiring the lock, when
50 * the lock is not owned by another thread. The method will return
51 * immediately if the current thread already owns the lock. This can
52 * be checked using methods {@link #isHeldByCurrentThread}, and {@link
53 * #getHoldCount}.
54 *
55 * <p>The constructor for this class accepts an optional
56 * <em>fairness</em> parameter. When set {@code true}, under
57 * contention, locks favor granting access to the longest-waiting
58 * thread. Otherwise this lock does not guarantee any particular
59 * access order. Programs using fair locks accessed by many threads
110 private final Sync sync;
111
112 /**
113 * Base of synchronization control for this lock. Subclassed
114 * into fair and nonfair versions below. Uses AQS state to
115 * represent the number of holds on the lock.
116 */
117 abstract static class Sync extends AbstractQueuedSynchronizer {
118 private static final long serialVersionUID = -5179523762034025860L;
119
120 /**
121 * Performs {@link Lock#lock}. The main reason for subclassing
122 * is to allow fast path for nonfair version.
123 */
124 abstract void lock();
125
126 /**
127 * Performs non-fair tryLock. tryAcquire is implemented in
128 * subclasses, but both need nonfair try for trylock method.
129 */
130 final boolean nonfairTryAcquire(int acquires) {
131 final Thread current = Thread.currentThread();
132 int c = getState();
133 if (c == 0) {
134 if (compareAndSetState(0, acquires)) {
135 setExclusiveOwnerThread(current);
136 return true;
137 }
138 }
139 else if (current == getExclusiveOwnerThread()) {
140 int nextc = c + acquires;
141 if (nextc < 0) // overflow
142 throw new Error("Maximum lock count exceeded");
143 setState(nextc);
144 return true;
145 }
146 return false;
147 }
148
149 protected final boolean tryRelease(int releases) {
150 int c = getState() - releases;
151 if (Thread.currentThread() != getExclusiveOwnerThread())
152 throw new IllegalMonitorStateException();
153 boolean free = false;
154 if (c == 0) {
155 free = true;
156 setExclusiveOwnerThread(null);
157 }
158 setState(c);
159 return free;
160 }
161
162 protected final boolean isHeldExclusively() {
163 // While we must in general read state before owner,
164 // we don't need to do so to check if current thread is owner
165 return getExclusiveOwnerThread() == Thread.currentThread();
166 }
167
168 final ConditionObject newCondition() {
186 /**
187 * Reconstitutes the instance from a stream (that is, deserializes it).
188 */
189 private void readObject(java.io.ObjectInputStream s)
190 throws java.io.IOException, ClassNotFoundException {
191 s.defaultReadObject();
192 setState(0); // reset to unlocked state
193 }
194 }
195
196 /**
197 * Sync object for non-fair locks
198 */
199 static final class NonfairSync extends Sync {
200 private static final long serialVersionUID = 7316153563782823691L;
201
202 /**
203 * Performs lock. Try immediate barge, backing up to normal
204 * acquire on failure.
205 */
206 final void lock() {
207 if (compareAndSetState(0, 1))
208 setExclusiveOwnerThread(Thread.currentThread());
209 else
210 acquire(1);
211 }
212
213 protected final boolean tryAcquire(int acquires) {
214 return nonfairTryAcquire(acquires);
215 }
216 }
217
218 /**
219 * Sync object for fair locks
220 */
221 static final class FairSync extends Sync {
222 private static final long serialVersionUID = -3000897897090466540L;
223
224 final void lock() {
225 acquire(1);
226 }
227
228 /**
229 * Fair version of tryAcquire. Don't grant access unless
230 * recursive call or no waiters or is first.
231 */
232 protected final boolean tryAcquire(int acquires) {
233 final Thread current = Thread.currentThread();
234 int c = getState();
235 if (c == 0) {
236 if (!hasQueuedPredecessors() &&
237 compareAndSetState(0, acquires)) {
238 setExclusiveOwnerThread(current);
239 return true;
240 }
241 }
242 else if (current == getExclusiveOwnerThread()) {
243 int nextc = c + acquires;
244 if (nextc < 0)
245 throw new Error("Maximum lock count exceeded");
246 setState(nextc);
247 return true;
248 }
249 return false;
250 }
251 }
|
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 */
24
25 /*
26 * This file is available under and governed by the GNU General Public
27 * License version 2 only, as published by the Free Software Foundation.
28 * However, the following notice accompanied the original version of this
29 * file:
30 *
31 * Written by Doug Lea with assistance from members of JCP JSR-166
32 * Expert Group and released to the public domain, as explained at
33 * http://creativecommons.org/publicdomain/zero/1.0/
34 */
35
36 package java.util.concurrent.locks;
37
38 import java.util.Collection;
39 import java.util.concurrent.TimeUnit;
40 import jdk.internal.vm.annotation.ReservedStackAccess;
41
42 /**
43 * A reentrant mutual exclusion {@link Lock} with the same basic
44 * behavior and semantics as the implicit monitor lock accessed using
45 * {@code synchronized} methods and statements, but with extended
46 * capabilities.
47 *
48 * <p>A {@code ReentrantLock} is <em>owned</em> by the thread last
49 * successfully locking, but not yet unlocking it. A thread invoking
50 * {@code lock} will return, successfully acquiring the lock, when
51 * the lock is not owned by another thread. The method will return
52 * immediately if the current thread already owns the lock. This can
53 * be checked using methods {@link #isHeldByCurrentThread}, and {@link
54 * #getHoldCount}.
55 *
56 * <p>The constructor for this class accepts an optional
57 * <em>fairness</em> parameter. When set {@code true}, under
58 * contention, locks favor granting access to the longest-waiting
59 * thread. Otherwise this lock does not guarantee any particular
60 * access order. Programs using fair locks accessed by many threads
111 private final Sync sync;
112
113 /**
114 * Base of synchronization control for this lock. Subclassed
115 * into fair and nonfair versions below. Uses AQS state to
116 * represent the number of holds on the lock.
117 */
118 abstract static class Sync extends AbstractQueuedSynchronizer {
119 private static final long serialVersionUID = -5179523762034025860L;
120
121 /**
122 * Performs {@link Lock#lock}. The main reason for subclassing
123 * is to allow fast path for nonfair version.
124 */
125 abstract void lock();
126
127 /**
128 * Performs non-fair tryLock. tryAcquire is implemented in
129 * subclasses, but both need nonfair try for trylock method.
130 */
131 @ReservedStackAccess
132 final boolean nonfairTryAcquire(int acquires) {
133 final Thread current = Thread.currentThread();
134 int c = getState();
135 if (c == 0) {
136 if (compareAndSetState(0, acquires)) {
137 setExclusiveOwnerThread(current);
138 return true;
139 }
140 }
141 else if (current == getExclusiveOwnerThread()) {
142 int nextc = c + acquires;
143 if (nextc < 0) // overflow
144 throw new Error("Maximum lock count exceeded");
145 setState(nextc);
146 return true;
147 }
148 return false;
149 }
150
151 @ReservedStackAccess
152 protected final boolean tryRelease(int releases) {
153 int c = getState() - releases;
154 if (Thread.currentThread() != getExclusiveOwnerThread())
155 throw new IllegalMonitorStateException();
156 boolean free = false;
157 if (c == 0) {
158 free = true;
159 setExclusiveOwnerThread(null);
160 }
161 setState(c);
162 return free;
163 }
164
165 protected final boolean isHeldExclusively() {
166 // While we must in general read state before owner,
167 // we don't need to do so to check if current thread is owner
168 return getExclusiveOwnerThread() == Thread.currentThread();
169 }
170
171 final ConditionObject newCondition() {
189 /**
190 * Reconstitutes the instance from a stream (that is, deserializes it).
191 */
192 private void readObject(java.io.ObjectInputStream s)
193 throws java.io.IOException, ClassNotFoundException {
194 s.defaultReadObject();
195 setState(0); // reset to unlocked state
196 }
197 }
198
199 /**
200 * Sync object for non-fair locks
201 */
202 static final class NonfairSync extends Sync {
203 private static final long serialVersionUID = 7316153563782823691L;
204
205 /**
206 * Performs lock. Try immediate barge, backing up to normal
207 * acquire on failure.
208 */
209 @ReservedStackAccess
210 final void lock() {
211 if (compareAndSetState(0, 1))
212 setExclusiveOwnerThread(Thread.currentThread());
213 else
214 acquire(1);
215 }
216
217 protected final boolean tryAcquire(int acquires) {
218 return nonfairTryAcquire(acquires);
219 }
220 }
221
222 /**
223 * Sync object for fair locks
224 */
225 static final class FairSync extends Sync {
226 private static final long serialVersionUID = -3000897897090466540L;
227
228 final void lock() {
229 acquire(1);
230 }
231
232 /**
233 * Fair version of tryAcquire. Don't grant access unless
234 * recursive call or no waiters or is first.
235 */
236 @ReservedStackAccess
237 protected final boolean tryAcquire(int acquires) {
238 final Thread current = Thread.currentThread();
239 int c = getState();
240 if (c == 0) {
241 if (!hasQueuedPredecessors() &&
242 compareAndSetState(0, acquires)) {
243 setExclusiveOwnerThread(current);
244 return true;
245 }
246 }
247 else if (current == getExclusiveOwnerThread()) {
248 int nextc = c + acquires;
249 if (nextc < 0)
250 throw new Error("Maximum lock count exceeded");
251 setState(nextc);
252 return true;
253 }
254 return false;
255 }
256 }
|