99 * locks: a deserialized lock is in the unlocked state, regardless of
100 * its state when serialized.
101 *
102 * <p>This lock supports a maximum of 2147483647 recursive locks by
103 * the same thread. Attempts to exceed this limit result in
104 * {@link Error} throws from locking methods.
105 *
106 * @since 1.5
107 * @author Doug Lea
108 */
109 public class ReentrantLock implements Lock, java.io.Serializable {
110 private static final long serialVersionUID = 7373984872572414699L;
111 /** Synchronizer providing all implementation mechanics */
112 private final Sync sync;
113
114 /**
115 * Base of synchronization control for this lock. Subclassed
116 * into fair and nonfair versions below. Uses AQS state to
117 * represent the number of holds on the lock.
118 */
119 static abstract class Sync extends AbstractQueuedSynchronizer {
120 private static final long serialVersionUID = -5179523762034025860L;
121
122 /**
123 * Performs {@link Lock#lock}. The main reason for subclassing
124 * is to allow fast path for nonfair version.
125 */
126 abstract void lock();
127
128 /**
129 * Performs non-fair tryLock. tryAcquire is
130 * implemented in subclasses, but both need nonfair
131 * try for trylock method.
132 */
133 final boolean nonfairTryAcquire(int acquires) {
134 final Thread current = Thread.currentThread();
135 int c = getState();
136 if (c == 0) {
137 if (compareAndSetState(0, acquires)) {
138 setExclusiveOwnerThread(current);
139 return true;
183 }
184
185 final boolean isLocked() {
186 return getState() != 0;
187 }
188
189 /**
190 * Reconstitutes this lock instance from a stream.
191 * @param s the stream
192 */
193 private void readObject(java.io.ObjectInputStream s)
194 throws java.io.IOException, ClassNotFoundException {
195 s.defaultReadObject();
196 setState(0); // reset to unlocked state
197 }
198 }
199
200 /**
201 * Sync object for non-fair locks
202 */
203 final static class NonfairSync extends Sync {
204 private static final long serialVersionUID = 7316153563782823691L;
205
206 /**
207 * Performs lock. Try immediate barge, backing up to normal
208 * acquire on failure.
209 */
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 final static 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 protected final boolean tryAcquire(int acquires) {
237 final Thread current = Thread.currentThread();
238 int c = getState();
239 if (c == 0) {
240 if (!hasQueuedPredecessors() &&
241 compareAndSetState(0, acquires)) {
242 setExclusiveOwnerThread(current);
243 return true;
244 }
245 }
252 }
253 return false;
254 }
255 }
256
257 /**
258 * Creates an instance of {@code ReentrantLock}.
259 * This is equivalent to using {@code ReentrantLock(false)}.
260 */
261 public ReentrantLock() {
262 sync = new NonfairSync();
263 }
264
265 /**
266 * Creates an instance of {@code ReentrantLock} with the
267 * given fairness policy.
268 *
269 * @param fair {@code true} if this lock should use a fair ordering policy
270 */
271 public ReentrantLock(boolean fair) {
272 sync = (fair)? new FairSync() : new NonfairSync();
273 }
274
275 /**
276 * Acquires the lock.
277 *
278 * <p>Acquires the lock if it is not held by another thread and returns
279 * immediately, setting the lock hold count to one.
280 *
281 * <p>If the current thread already holds the lock then the hold
282 * count is incremented by one and the method returns immediately.
283 *
284 * <p>If the lock is held by another thread then the
285 * current thread becomes disabled for thread scheduling
286 * purposes and lies dormant until the lock has been acquired,
287 * at which time the lock hold count is set to one.
288 */
289 public void lock() {
290 sync.lock();
291 }
292
423 *
424 * <p>If the specified waiting time elapses then the value {@code false}
425 * is returned. If the time is less than or equal to zero, the method
426 * will not wait at all.
427 *
428 * <p>In this implementation, as this method is an explicit
429 * interruption point, preference is given to responding to the
430 * interrupt over normal or reentrant acquisition of the lock, and
431 * over reporting the elapse of the waiting time.
432 *
433 * @param timeout the time to wait for the lock
434 * @param unit the time unit of the timeout argument
435 * @return {@code true} if the lock was free and was acquired by the
436 * current thread, or the lock was already held by the current
437 * thread; and {@code false} if the waiting time elapsed before
438 * the lock could be acquired
439 * @throws InterruptedException if the current thread is interrupted
440 * @throws NullPointerException if the time unit is null
441 *
442 */
443 public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
444 return sync.tryAcquireNanos(1, unit.toNanos(timeout));
445 }
446
447 /**
448 * Attempts to release this lock.
449 *
450 * <p>If the current thread is the holder of this lock then the hold
451 * count is decremented. If the hold count is now zero then the lock
452 * is released. If the current thread is not the holder of this
453 * lock then {@link IllegalMonitorStateException} is thrown.
454 *
455 * @throws IllegalMonitorStateException if the current thread does not
456 * hold this lock
457 */
458 public void unlock() {
459 sync.release(1);
460 }
461
462 /**
463 * Returns a {@link Condition} instance for use with this
|
99 * locks: a deserialized lock is in the unlocked state, regardless of
100 * its state when serialized.
101 *
102 * <p>This lock supports a maximum of 2147483647 recursive locks by
103 * the same thread. Attempts to exceed this limit result in
104 * {@link Error} throws from locking methods.
105 *
106 * @since 1.5
107 * @author Doug Lea
108 */
109 public class ReentrantLock implements Lock, java.io.Serializable {
110 private static final long serialVersionUID = 7373984872572414699L;
111 /** Synchronizer providing all implementation mechanics */
112 private final Sync sync;
113
114 /**
115 * Base of synchronization control for this lock. Subclassed
116 * into fair and nonfair versions below. Uses AQS state to
117 * represent the number of holds on the lock.
118 */
119 abstract static class Sync extends AbstractQueuedSynchronizer {
120 private static final long serialVersionUID = -5179523762034025860L;
121
122 /**
123 * Performs {@link Lock#lock}. The main reason for subclassing
124 * is to allow fast path for nonfair version.
125 */
126 abstract void lock();
127
128 /**
129 * Performs non-fair tryLock. tryAcquire is
130 * implemented in subclasses, but both need nonfair
131 * try for trylock method.
132 */
133 final boolean nonfairTryAcquire(int acquires) {
134 final Thread current = Thread.currentThread();
135 int c = getState();
136 if (c == 0) {
137 if (compareAndSetState(0, acquires)) {
138 setExclusiveOwnerThread(current);
139 return true;
183 }
184
185 final boolean isLocked() {
186 return getState() != 0;
187 }
188
189 /**
190 * Reconstitutes this lock instance from a stream.
191 * @param s the stream
192 */
193 private void readObject(java.io.ObjectInputStream s)
194 throws java.io.IOException, ClassNotFoundException {
195 s.defaultReadObject();
196 setState(0); // reset to unlocked state
197 }
198 }
199
200 /**
201 * Sync object for non-fair locks
202 */
203 static final class NonfairSync extends Sync {
204 private static final long serialVersionUID = 7316153563782823691L;
205
206 /**
207 * Performs lock. Try immediate barge, backing up to normal
208 * acquire on failure.
209 */
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 protected final boolean tryAcquire(int acquires) {
237 final Thread current = Thread.currentThread();
238 int c = getState();
239 if (c == 0) {
240 if (!hasQueuedPredecessors() &&
241 compareAndSetState(0, acquires)) {
242 setExclusiveOwnerThread(current);
243 return true;
244 }
245 }
252 }
253 return false;
254 }
255 }
256
257 /**
258 * Creates an instance of {@code ReentrantLock}.
259 * This is equivalent to using {@code ReentrantLock(false)}.
260 */
261 public ReentrantLock() {
262 sync = new NonfairSync();
263 }
264
265 /**
266 * Creates an instance of {@code ReentrantLock} with the
267 * given fairness policy.
268 *
269 * @param fair {@code true} if this lock should use a fair ordering policy
270 */
271 public ReentrantLock(boolean fair) {
272 sync = fair ? new FairSync() : new NonfairSync();
273 }
274
275 /**
276 * Acquires the lock.
277 *
278 * <p>Acquires the lock if it is not held by another thread and returns
279 * immediately, setting the lock hold count to one.
280 *
281 * <p>If the current thread already holds the lock then the hold
282 * count is incremented by one and the method returns immediately.
283 *
284 * <p>If the lock is held by another thread then the
285 * current thread becomes disabled for thread scheduling
286 * purposes and lies dormant until the lock has been acquired,
287 * at which time the lock hold count is set to one.
288 */
289 public void lock() {
290 sync.lock();
291 }
292
423 *
424 * <p>If the specified waiting time elapses then the value {@code false}
425 * is returned. If the time is less than or equal to zero, the method
426 * will not wait at all.
427 *
428 * <p>In this implementation, as this method is an explicit
429 * interruption point, preference is given to responding to the
430 * interrupt over normal or reentrant acquisition of the lock, and
431 * over reporting the elapse of the waiting time.
432 *
433 * @param timeout the time to wait for the lock
434 * @param unit the time unit of the timeout argument
435 * @return {@code true} if the lock was free and was acquired by the
436 * current thread, or the lock was already held by the current
437 * thread; and {@code false} if the waiting time elapsed before
438 * the lock could be acquired
439 * @throws InterruptedException if the current thread is interrupted
440 * @throws NullPointerException if the time unit is null
441 *
442 */
443 public boolean tryLock(long timeout, TimeUnit unit)
444 throws InterruptedException {
445 return sync.tryAcquireNanos(1, unit.toNanos(timeout));
446 }
447
448 /**
449 * Attempts to release this lock.
450 *
451 * <p>If the current thread is the holder of this lock then the hold
452 * count is decremented. If the hold count is now zero then the lock
453 * is released. If the current thread is not the holder of this
454 * lock then {@link IllegalMonitorStateException} is thrown.
455 *
456 * @throws IllegalMonitorStateException if the current thread does not
457 * hold this lock
458 */
459 public void unlock() {
460 sync.release(1);
461 }
462
463 /**
464 * Returns a {@link Condition} instance for use with this
|