src/share/classes/java/util/concurrent/Semaphore.java

Print this page




 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: