ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/Semaphore.java
(Generate patch)

Comparing jsr166/src/main/java/util/concurrent/Semaphore.java (file contents):
Revision 1.22 by dl, Sat Dec 27 14:48:44 2003 UTC vs.
Revision 1.23 by dl, Sat Dec 27 17:19:03 2003 UTC

# Line 118 | Line 118 | import java.util.concurrent.atomic.*;
118   *
119   */
120  
121 < public class Semaphore extends AbstractQueuedSynchronizer implements java.io.Serializable {
121 > public class Semaphore implements java.io.Serializable {
122      private static final long serialVersionUID = -3222578661600680210L;
123 <    private final boolean fair;
123 >    /** Sync mechanics via AbstractQueuedSynchronizer subclass */
124 >    private final Sync sync;
125 >
126 >
127 >    private final static class Sync extends AbstractQueuedSynchronizer {
128 >        final boolean fair;
129 >        Sync(int permits, boolean fair) {
130 >            this.fair = fair;
131 >            getState().set(permits);
132 >        }
133 >        
134 >        public final int acquireSharedState(boolean isQueued, int acquires,
135 >                                            Thread current) {
136 >            final AtomicInteger perms = getState();
137 >            if (!isQueued && fair && hasWaiters())
138 >                return -1;
139 >            for (;;) {
140 >                int available = perms.get();
141 >                int remaining = available - acquires;
142 >                if (remaining < 0 ||
143 >                    perms.compareAndSet(available, remaining))
144 >                    return remaining;
145 >            }
146 >        }
147 >        
148 >        public final boolean releaseSharedState(int releases) {
149 >            final AtomicInteger perms = getState();
150 >            for (;;) {
151 >                int p = perms.get();
152 >                if (perms.compareAndSet(p, p + releases))
153 >                    return true;
154 >            }
155 >        }
156 >        
157 >        public final int acquireExclusiveState(boolean isQueued,
158 >                                               int acquires,
159 >                                               Thread current) {
160 >            throw new UnsupportedOperationException();
161 >        }
162 >        
163 >        public final boolean releaseExclusiveState(int releases) {
164 >            throw new UnsupportedOperationException();
165 >        }
166 >        
167 >        public final void checkConditionAccess(Thread thread, boolean waiting) {
168 >            throw new UnsupportedOperationException();
169 >        }
170 >
171 >    }
172  
173      /**
174       * Construct a <tt>Semaphore</tt> with the given number of
# Line 132 | Line 180 | public class Semaphore extends AbstractQ
180       * first-out granting of permits under contention, else false.
181       */
182      public Semaphore(int permits, boolean fair) {
183 <        this.fair = fair;
136 <        getState().set(permits);
183 >        sync = new Sync(permits, fair);
184      }
185  
186      /**
# Line 166 | Line 213 | public class Semaphore extends AbstractQ
213       * @see Thread#interrupt
214       */
215      public void acquire() throws InterruptedException {
216 <        acquireSharedInterruptibly(1);
216 >        sync.acquireSharedInterruptibly(1);
217      }
218  
219      /**
# Line 189 | Line 236 | public class Semaphore extends AbstractQ
236       *
237       */
238      public void acquireUninterruptibly() {
239 <        acquireSharedUninterruptibly(1);
239 >        sync.acquireSharedUninterruptibly(1);
240      }
241  
242      /**
# Line 206 | Line 253 | public class Semaphore extends AbstractQ
253       * otherwise.
254       */
255      public boolean tryAcquire() {
256 <        return acquireSharedState(false, 1, null) >= 0;
256 >        return sync.acquireSharedState(false, 1, null) >= 0;
257      }
258  
259      /**
# Line 252 | Line 299 | public class Semaphore extends AbstractQ
299       */
300      public boolean tryAcquire(long timeout, TimeUnit unit)
301          throws InterruptedException {
302 <        return acquireSharedTimed(1, unit.toNanos(timeout));
302 >        return sync.acquireSharedTimed(1, unit.toNanos(timeout));
303      }
304  
305      /**
# Line 268 | Line 315 | public class Semaphore extends AbstractQ
315       * in the application.
316       */
317      public void release() {
318 <        releaseShared(1);
318 >        sync.releaseShared(1);
319      }
320        
321      /**
# Line 312 | Line 359 | public class Semaphore extends AbstractQ
359       */
360      public void acquire(int permits) throws InterruptedException {
361          if (permits < 0) throw new IllegalArgumentException();
362 <        acquireSharedInterruptibly(permits);
362 >        sync.acquireSharedInterruptibly(permits);
363      }
364  
365      /**
# Line 341 | Line 388 | public class Semaphore extends AbstractQ
388       */
389      public void acquireUninterruptibly(int permits) {
390          if (permits < 0) throw new IllegalArgumentException();
391 <        acquireSharedUninterruptibly(permits);
391 >        sync.acquireSharedUninterruptibly(permits);
392      }
393  
394      /**
# Line 363 | Line 410 | public class Semaphore extends AbstractQ
410       */
411      public boolean tryAcquire(int permits) {
412          if (permits < 0) throw new IllegalArgumentException();
413 <        return acquireSharedState(false, permits, null) >= 0;
413 >        return sync.acquireSharedState(false, permits, null) >= 0;
414      }
415  
416      /**
# Line 420 | Line 467 | public class Semaphore extends AbstractQ
467      public boolean tryAcquire(int permits, long timeout, TimeUnit unit)
468          throws InterruptedException {
469          if (permits < 0) throw new IllegalArgumentException();
470 <        return acquireSharedTimed(permits, unit.toNanos(timeout));
470 >        return sync.acquireSharedTimed(permits, unit.toNanos(timeout));
471      }
472  
473  
# Line 450 | Line 497 | public class Semaphore extends AbstractQ
497       */
498      public void release(int permits) {
499          if (permits < 0) throw new IllegalArgumentException();
500 <        releaseShared(permits);
500 >        sync.releaseShared(permits);
501      }
502  
503      /**
# Line 459 | Line 506 | public class Semaphore extends AbstractQ
506       * @return the number of permits available in this semaphore.
507       */
508      public int availablePermits() {
509 <        return getState().get();
509 >        return sync.getState().get();
510      }
511  
512      /**
# Line 474 | Line 521 | public class Semaphore extends AbstractQ
521       */
522      protected void reducePermits(int reduction) {
523          if (reduction < 0) throw new IllegalArgumentException();
524 <        getState().getAndAdd(-reduction);
524 >        sync.getState().getAndAdd(-reduction);
525      }
526  
527      /**
# Line 482 | Line 529 | public class Semaphore extends AbstractQ
529       * @return true if this semaphore has fairness set true.
530       */
531      public boolean isFair() {
532 <        return fair;
532 >        return sync.fair;
533      }
534  
488    // Implement abstract methods
535  
536      /**
537 <     * Sets internal state to indicate permits acquired if available
538 <     */
539 <    protected final int acquireSharedState(boolean isQueued, int acquires,
540 <                                     Thread current) {
541 <        final AtomicInteger perms = getState();
542 <        if (!isQueued && fair && hasWaiters())
543 <            return -1;
544 <        for (;;) {
499 <            int available = perms.get();
500 <            int remaining = available - acquires;
501 <            if (remaining < 0 ||
502 <                perms.compareAndSet(available, remaining))
503 <                return remaining;
504 <        }
505 <    }
506 <    
507 <    /**
508 <     * Sets internal state to indicate permits have been released
537 >     * Queries whether any threads are waiting to acquire. Note that
538 >     * because cancellations may occur at any time, a <tt>true</tt>
539 >     * return does not guarantee that any other thread will ever
540 >     * acquire.  This method is designed primarily for use in
541 >     * monitoring of the system state.
542 >     *
543 >     * @return true if there may be other threads waiting to acquire
544 >     * the lock.
545       */
546 <    protected final boolean releaseSharedState(int releases) {
547 <        final AtomicInteger perms = getState();
512 <        for (;;) {
513 <            int p = perms.get();
514 <            if (perms.compareAndSet(p, p + releases))
515 <                return true;
516 <        }
546 >    public final boolean hasWaiters() {
547 >        return sync.hasWaiters();
548      }
549  
519    /**
520     * Always throws UnsupportedOperationException
521     */
522    protected final int acquireExclusiveState(boolean isQueued, int acquires,
523                                        Thread current) {
524        throw new UnsupportedOperationException();
525    }
550  
551      /**
552 <     * Always throws UnsupportedOperationException
552 >     * Returns an estimate of the number of threads waiting to
553 >     * acquire.  The value is only an estimate because the number of
554 >     * threads may change dynamically while this method traverses
555 >     * internal data structures.  This method is designed for use in
556 >     * monitoring of the system state, not for synchronization
557 >     * control.
558 >     * @return the estimated number of threads waiting for this lock
559       */
560 <    protected final boolean releaseExclusiveState(int releases) {
561 <        throw new UnsupportedOperationException();
560 >    public final int getQueueLength() {
561 >        return sync.getQueueLength();
562      }
563  
564      /**
565 <     * Always throws UnsupportedOperationException
565 >     * Returns a collection containing threads that may be waiting to
566 >     * acquire.  Because the actual set of threads may change
567 >     * dynamically while constructing this result, the returned
568 >     * collection is only a best-effort estimate.  The elements of the
569 >     * returned collection are in no particular order.  This method is
570 >     * designed to facilitate construction of subclasses that provide
571 >     * more extensive monitoring facilities.
572 >     * @return the collection of threads
573       */
574 <    protected final void checkConditionAccess(Thread thread, boolean waiting) {
575 <        throw new UnsupportedOperationException();
574 >    protected Collection<Thread> getQueuedThreads() {
575 >        return sync.getQueuedThreads();
576      }
577 <
577 >    
578   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines