206 int next = current - reductions;
207 if (next > current) // underflow
208 throw new Error("Permit count underflow");
209 if (compareAndSetState(current, next))
210 return;
211 }
212 }
213
214 final int drainPermits() {
215 for (;;) {
216 int current = getState();
217 if (current == 0 || compareAndSetState(current, 0))
218 return current;
219 }
220 }
221 }
222
223 /**
224 * NonFair version
225 */
226 final static class NonfairSync extends Sync {
227 private static final long serialVersionUID = -2694183684443567898L;
228
229 NonfairSync(int permits) {
230 super(permits);
231 }
232
233 protected int tryAcquireShared(int acquires) {
234 return nonfairTryAcquireShared(acquires);
235 }
236 }
237
238 /**
239 * Fair version
240 */
241 final static class FairSync extends Sync {
242 private static final long serialVersionUID = 2014338818796000944L;
243
244 FairSync(int permits) {
245 super(permits);
246 }
247
248 protected int tryAcquireShared(int acquires) {
249 for (;;) {
250 if (hasQueuedPredecessors())
251 return -1;
252 int available = getState();
253 int remaining = available - acquires;
254 if (remaining < 0 ||
255 compareAndSetState(available, remaining))
256 return remaining;
257 }
258 }
259 }
260
261 /**
265 * @param permits the initial number of permits available.
266 * This value may be negative, in which case releases
267 * must occur before any acquires will be granted.
268 */
269 public Semaphore(int permits) {
270 sync = new NonfairSync(permits);
271 }
272
273 /**
274 * Creates a {@code Semaphore} with the given number of
275 * permits and the given fairness setting.
276 *
277 * @param permits the initial number of permits available.
278 * This value may be negative, in which case releases
279 * must occur before any acquires will be granted.
280 * @param fair {@code true} if this semaphore will guarantee
281 * first-in first-out granting of permits under contention,
282 * else {@code false}
283 */
284 public Semaphore(int permits, boolean fair) {
285 sync = (fair)? new FairSync(permits) : new NonfairSync(permits);
286 }
287
288 /**
289 * Acquires a permit from this semaphore, blocking until one is
290 * available, or the thread is {@linkplain Thread#interrupt interrupted}.
291 *
292 * <p>Acquires a permit, if one is available and returns immediately,
293 * reducing the number of available permits by one.
294 *
295 * <p>If no permit is available then the current thread becomes
296 * disabled for thread scheduling purposes and lies dormant until
297 * one of two things happens:
298 * <ul>
299 * <li>Some other thread invokes the {@link #release} method for this
300 * semaphore and the current thread is next to be assigned a permit; or
301 * <li>Some other thread {@linkplain Thread#interrupt interrupts}
302 * the current thread.
303 * </ul>
304 *
305 * <p>If the current thread:
|
206 int next = current - reductions;
207 if (next > current) // underflow
208 throw new Error("Permit count underflow");
209 if (compareAndSetState(current, next))
210 return;
211 }
212 }
213
214 final int drainPermits() {
215 for (;;) {
216 int current = getState();
217 if (current == 0 || compareAndSetState(current, 0))
218 return current;
219 }
220 }
221 }
222
223 /**
224 * NonFair version
225 */
226 static final class NonfairSync extends Sync {
227 private static final long serialVersionUID = -2694183684443567898L;
228
229 NonfairSync(int permits) {
230 super(permits);
231 }
232
233 protected int tryAcquireShared(int acquires) {
234 return nonfairTryAcquireShared(acquires);
235 }
236 }
237
238 /**
239 * Fair version
240 */
241 static final class FairSync extends Sync {
242 private static final long serialVersionUID = 2014338818796000944L;
243
244 FairSync(int permits) {
245 super(permits);
246 }
247
248 protected int tryAcquireShared(int acquires) {
249 for (;;) {
250 if (hasQueuedPredecessors())
251 return -1;
252 int available = getState();
253 int remaining = available - acquires;
254 if (remaining < 0 ||
255 compareAndSetState(available, remaining))
256 return remaining;
257 }
258 }
259 }
260
261 /**
265 * @param permits the initial number of permits available.
266 * This value may be negative, in which case releases
267 * must occur before any acquires will be granted.
268 */
269 public Semaphore(int permits) {
270 sync = new NonfairSync(permits);
271 }
272
273 /**
274 * Creates a {@code Semaphore} with the given number of
275 * permits and the given fairness setting.
276 *
277 * @param permits the initial number of permits available.
278 * This value may be negative, in which case releases
279 * must occur before any acquires will be granted.
280 * @param fair {@code true} if this semaphore will guarantee
281 * first-in first-out granting of permits under contention,
282 * else {@code false}
283 */
284 public Semaphore(int permits, boolean fair) {
285 sync = fair ? new FairSync(permits) : new NonfairSync(permits);
286 }
287
288 /**
289 * Acquires a permit from this semaphore, blocking until one is
290 * available, or the thread is {@linkplain Thread#interrupt interrupted}.
291 *
292 * <p>Acquires a permit, if one is available and returns immediately,
293 * reducing the number of available permits by one.
294 *
295 * <p>If no permit is available then the current thread becomes
296 * disabled for thread scheduling purposes and lies dormant until
297 * one of two things happens:
298 * <ul>
299 * <li>Some other thread invokes the {@link #release} method for this
300 * semaphore and the current thread is next to be assigned a permit; or
301 * <li>Some other thread {@linkplain Thread#interrupt interrupts}
302 * the current thread.
303 * </ul>
304 *
305 * <p>If the current thread:
|