@@ -119,39 +119,63 @@ abstract static class Sync extends AbstractQueuedSynchronizer {
119
119
private static final long serialVersionUID = -5179523762034025860L ;
120
120
121
121
/**
122
- * Performs non-fair tryLock. tryAcquire is implemented in
123
- * subclasses, but both need nonfair try for trylock method.
122
+ * Performs non-fair tryLock.
124
123
*/
125
124
@ ReservedStackAccess
126
- final boolean nonfairTryAcquire ( int acquires ) {
127
- final Thread current = Thread .currentThread ();
125
+ final boolean tryLock ( ) {
126
+ Thread current = Thread .currentThread ();
128
127
int c = getState ();
129
128
if (c == 0 ) {
130
- if (compareAndSetState (0 , acquires )) {
129
+ if (compareAndSetState (0 , 1 )) {
131
130
setExclusiveOwnerThread (current );
132
131
return true ;
133
132
}
134
- }
135
- else if (current == getExclusiveOwnerThread ()) {
136
- int nextc = c + acquires ;
137
- if (nextc < 0 ) // overflow
133
+ } else if (getExclusiveOwnerThread () == current ) {
134
+ if (++c < 0 ) // overflow
138
135
throw new Error ("Maximum lock count exceeded" );
139
- setState (nextc );
136
+ setState (c );
140
137
return true ;
141
138
}
142
139
return false ;
143
140
}
144
141
142
+ /**
143
+ * Checks for reentrancy and acquires if lock immediately
144
+ * available under fair vs nonfair rules. Locking methods
145
+ * perform initialTryLock check before relaying to
146
+ * corresponding AQS acquire methods.
147
+ */
148
+ abstract boolean initialTryLock ();
149
+
150
+ @ ReservedStackAccess
151
+ final void lock () {
152
+ if (!initialTryLock ())
153
+ acquire (1 );
154
+ }
155
+
156
+ @ ReservedStackAccess
157
+ final void lockInterruptibly () throws InterruptedException {
158
+ if (Thread .interrupted ())
159
+ throw new InterruptedException ();
160
+ if (!initialTryLock ())
161
+ acquireInterruptibly (1 );
162
+ }
163
+
164
+ @ ReservedStackAccess
165
+ final boolean tryLockNanos (long nanos ) throws InterruptedException {
166
+ if (Thread .interrupted ())
167
+ throw new InterruptedException ();
168
+ return initialTryLock () || tryAcquireNanos (1 , nanos );
169
+ }
170
+
145
171
@ ReservedStackAccess
146
172
protected final boolean tryRelease (int releases ) {
147
173
int c = getState () - releases ;
148
- if (Thread . currentThread () != getExclusiveOwnerThread ())
174
+ if (getExclusiveOwnerThread () != Thread . currentThread ())
149
175
throw new IllegalMonitorStateException ();
150
- boolean free = false ;
151
- if (c == 0 ) {
152
- free = true ;
176
+ boolean free = (c == 0 );
177
+ if (free )
153
178
setExclusiveOwnerThread (null );
154
- }
155
179
setState (c );
156
180
return free ;
157
181
}
@@ -195,8 +219,31 @@ private void readObject(java.io.ObjectInputStream s)
195
219
*/
196
220
static final class NonfairSync extends Sync {
197
221
private static final long serialVersionUID = 7316153563782823691L ;
222
+
223
+ final boolean initialTryLock () {
224
+ Thread current = Thread .currentThread ();
225
+ if (compareAndSetState (0 , 1 )) { // first attempt is unguarded
226
+ setExclusiveOwnerThread (current );
227
+ return true ;
228
+ } else if (getExclusiveOwnerThread () == current ) {
229
+ int c = getState () + 1 ;
230
+ if (c < 0 ) // overflow
231
+ throw new Error ("Maximum lock count exceeded" );
232
+ setState (c );
233
+ return true ;
234
+ } else
235
+ return false ;
236
+ }
237
+
238
+ /**
239
+ * Acquire for non-reentrant cases after initialTryLock prescreen
240
+ */
198
241
protected final boolean tryAcquire (int acquires ) {
199
- return nonfairTryAcquire (acquires );
242
+ if (getState () == 0 && compareAndSetState (0 , acquires )) {
243
+ setExclusiveOwnerThread (Thread .currentThread ());
244
+ return true ;
245
+ }
246
+ return false ;
200
247
}
201
248
}
202
249
@@ -205,26 +252,34 @@ protected final boolean tryAcquire(int acquires) {
205
252
*/
206
253
static final class FairSync extends Sync {
207
254
private static final long serialVersionUID = -3000897897090466540L ;
255
+
208
256
/**
209
- * Fair version of tryAcquire. Don't grant access unless
210
- * recursive call or no waiters or is first.
257
+ * Acquires only if reentrant or queue is empty.
211
258
*/
212
- @ ReservedStackAccess
213
- protected final boolean tryAcquire (int acquires ) {
214
- final Thread current = Thread .currentThread ();
259
+ final boolean initialTryLock () {
260
+ Thread current = Thread .currentThread ();
215
261
int c = getState ();
216
262
if (c == 0 ) {
217
- if (!hasQueuedPredecessors () &&
218
- compareAndSetState (0 , acquires )) {
263
+ if (!hasQueuedThreads () && compareAndSetState (0 , 1 )) {
219
264
setExclusiveOwnerThread (current );
220
265
return true ;
221
266
}
222
- }
223
- else if (current == getExclusiveOwnerThread ()) {
224
- int nextc = c + acquires ;
225
- if (nextc < 0 )
267
+ } else if (getExclusiveOwnerThread () == current ) {
268
+ if (++c < 0 ) // overflow
226
269
throw new Error ("Maximum lock count exceeded" );
227
- setState (nextc );
270
+ setState (c );
271
+ return true ;
272
+ }
273
+ return false ;
274
+ }
275
+
276
+ /**
277
+ * Acquires only if thread is first waiter or empty
278
+ */
279
+ protected final boolean tryAcquire (int acquires ) {
280
+ if (getState () == 0 && !hasQueuedPredecessors () &&
281
+ compareAndSetState (0 , acquires )) {
282
+ setExclusiveOwnerThread (Thread .currentThread ());
228
283
return true ;
229
284
}
230
285
return false ;
@@ -264,7 +319,7 @@ public ReentrantLock(boolean fair) {
264
319
* at which time the lock hold count is set to one.
265
320
*/
266
321
public void lock () {
267
- sync .acquire ( 1 );
322
+ sync .lock ( );
268
323
}
269
324
270
325
/**
@@ -314,7 +369,7 @@ public void lock() {
314
369
* @throws InterruptedException if the current thread is interrupted
315
370
*/
316
371
public void lockInterruptibly () throws InterruptedException {
317
- sync .acquireInterruptibly ( 1 );
372
+ sync .lockInterruptibly ( );
318
373
}
319
374
320
375
/**
@@ -344,7 +399,7 @@ public void lockInterruptibly() throws InterruptedException {
344
399
* thread; and {@code false} otherwise
345
400
*/
346
401
public boolean tryLock () {
347
- return sync .nonfairTryAcquire ( 1 );
402
+ return sync .tryLock ( );
348
403
}
349
404
350
405
/**
@@ -421,7 +476,7 @@ public boolean tryLock() {
421
476
*/
422
477
public boolean tryLock (long timeout , TimeUnit unit )
423
478
throws InterruptedException {
424
- return sync .tryAcquireNanos ( 1 , unit .toNanos (timeout ));
479
+ return sync .tryLockNanos ( unit .toNanos (timeout ));
425
480
}
426
481
427
482
/**
0 commit comments