ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/Semaphore.java
Revision: 1.1
Committed: Wed May 14 21:30:48 2003 UTC (21 years ago) by tim
Branch: MAIN
Log Message:
Moved main source rooted at . to ./src/main
Moved test source rooted at ./etc/testcases to ./src/test

File Contents

# User Rev Content
1 tim 1.1 package java.util.concurrent;
2    
3     /**
4     * A counting semaphore. Conceptually, a semaphore maintains a set of
5     * permits. Each {@link #acquire} blocks if necessary until a permit is
6     * available, and then takes it. Each {@link #release} adds a permit,
7     * potentially releasing a blocking acquirer.
8     * However, no actual permit objects are used; the <tt>Semaphore</tt> just
9     * keeps a count of the number available and acts accordingly.
10     *
11     * <p>Semaphores are used to restrict the number of threads than can
12     * access some (physical or logical) resource. For example, here is
13     * a class that uses a semaphore to control access to a pool of items:
14     * <pre>
15     * class Pool {
16     * private static final MAX_AVAILABLE = 100;
17     * private final Semaphore available = new Semaphore(MAX_AVAILABLE);
18     *
19     * public Object getItem() throws InterruptedException {
20     * available.acquire();
21     * return getNextAvailableItem();
22     * }
23     *
24     * public void putItem(Object x) {
25     * if (markAsUnused(x))
26     * available.release();
27     * }
28     *
29     * // Not a particularly efficient data structure; just for demo
30     *
31     * protected Object[] items = ... whatever kinds of items being managed
32     * protected boolean[] used = new boolean[MAX_AVAILABLE];
33     *
34     * protected synchronized Object getNextAvailableItem() {
35     * for (int i = 0; i < MAX_AVAILABLE; ++i) {
36     * if (!used[i]) {
37     * used[i] = true;
38     * return items[i];
39     * }
40     * }
41     * return null; // not reached
42     * }
43     *
44     * protected synchronized boolean markAsUnused(Object item) {
45     * for (int i = 0; i < MAX_AVAILABLE; ++i) {
46     * if (item == items[i]) {
47     * if (used[i]) {
48     * used[i] = false;
49     * return true;
50     * }
51     * else
52     * return false;
53     * }
54     * }
55     * return false;
56     * }
57     *
58     * }
59     * </pre>
60     * <p>Before obtaining an item each thread must acquire a permit from the
61     * semaphore, guaranteeing that an item is available for use. When the
62     * thread has finished with the item it is returned back to the pool and
63     * a permit is returned to the semaphore, allowing another thread to
64     * acquire that item.
65     * Note that no synchronization lock is held when {@link #acquire} is
66     * called as that would prevent an item from being returned to the pool.
67     * The semaphore encapsulates the synchronization needed to restrict access to
68     * the pool, separately from any synchronization needed to maintain the
69     * consistency of the pool itself.
70     *
71     * <p>A semaphore initialized to one, and which is used such that it only
72     * has at most one permit available, can serve as a mutual exclusion lock.
73     * This is more
74     * commonly known as a <em>binary semaphore</em>, because it only has two
75     * states: one permit available, or zero permits available.
76     * When used in this way, the binary semaphore has the property (unlike many
77     * {@link Lock} implementations, that the &quot;lock&quot; can be released by
78     * a thread other than the owner (as semaphores have no notion of ownership).
79     * This can be useful in some specialised contexts, such as deadlock recovery.
80     *
81     * <p>This class makes no guarantees about the order in which threads
82     * acquire permits. In particular, barging is permitted, that is, a thread
83     * invoking {@link #acquire} can be allocated a permit ahead of a thread
84     * that has been waiting. If you need more deterministic guarantees, consider
85     * using {@link FifoSemaphore}.
86     *
87     *
88     * @since 1.5
89     * @spec JSR-166
90     * @revised $Date: 2003/01/29 07:08:21 $
91     * @editor $Author: dholmes $
92     *
93     */
94     public class Semaphore {
95    
96     private long permits = 0;
97    
98     /**
99     * Construct a <tt>Semaphore</tt> with the given number of
100     * permits.
101     * @param permits the initial number of permits available
102     */
103     public Semaphore(long permits) {
104     this.permits = permits;
105     }
106    
107     /**
108     * Acquires a permit from this semaphore, blocking until one is
109     * available, or the thread is {@link Thread#interrupt interrupted}.
110     *
111     * <p>Acquires a permit, if one is available and returns immediately,
112     * reducing the number of available permits by one.
113     * <p>If no permit is available then the current thread becomes
114     * disabled for thread scheduling purposes and lies dormant until
115     * one of two things happens:
116     * <ul>
117     * <li>Some other thread invokes the {@link #release} method for this
118     * semaphore and the current thread happens to be chosen as the
119     * thread to receive the permit; or
120     * <li>Some other thread {@link Thread#interrupt interrupts} the current
121     * thread.
122     * </ul>
123     *
124     * <p>If the current thread:
125     * <ul>
126     * <li>has its interrupted status set on entry to this method; or
127     * <li>is {@link Thread#interrupt interrupted} while waiting
128     * for a permit,
129     * </ul>
130     * then {@link InterruptedException} is thrown and the current thread's
131     * interrupted status is cleared.
132     *
133     * @throws InterruptedException if the current thread is interrupted
134     *
135     * @see Thread#interrupt
136     */
137     public void acquire() throws InterruptedException {}
138    
139     /**
140     * Acquires a permit from this semaphore, blocking until one is
141     * available.
142     *
143     * <p>Acquires a permit, if one is available and returns immediately,
144     * reducing the number of available permits by one.
145     * <p>If no permit is available then the current thread becomes
146     * disabled for thread scheduling purposes and lies dormant until
147     * some other thread invokes the {@link #release} method for this
148     * semaphore and the current thread happens to be chosen as the
149     * thread to receive the permit.
150     *
151     * <p>If the current thread
152     * is {@link Thread#interrupt interrupted} while waiting
153     * for a permit then it will continue to wait, but the time at which
154     * the thread is assigned a permit may change compared to the time it
155     * would have received the permit had no interruption occurred. When the
156     * thread does return from this method its interrupt status will be set.
157     *
158     */
159     public void acquireUninterruptibly() {}
160    
161     /**
162     * Acquires a permit from this semaphore, only if one is available at the
163     * time of invocation.
164     * <p>Acquires a permit, if one is available and returns immediately,
165     * with the value <tt>true</tt>,
166     * reducing the number of available permits by one.
167     *
168     * <p>If no permit is available then this method will return
169     * immediately with the value <tt>false</tt>.
170     *
171     * @return <tt>true</tt> if a permit was acquired and <tt>false</tt>
172     * otherwise.
173     */
174     public boolean tryAcquire() {
175     return false;
176     }
177    
178     /**
179     * Acquires a permit from this semaphore, if one becomes available
180     * within the given waiting time and the
181     * current thread has not been {@link Thread#interrupt interrupted}.
182     * <p>Acquires a permit, if one is available and returns immediately,
183     * with the value <tt>true</tt>,
184     * reducing the number of available permits by one.
185     * <p>If no permit is available then
186     * the current thread becomes disabled for thread scheduling
187     * purposes and lies dormant until one of three things happens:
188     * <ul>
189     * <li>Some other thread invokes the {@link #release} method for this
190     * semaphore and the current thread happens to be chosen as the
191     * thread to receive the permit; or
192     * <li>Some other thread {@link Thread#interrupt interrupts} the current
193     * thread; or
194     * <li>The specified waiting time elapses.
195     * </ul>
196     * <p>If a permit is acquired then the value <tt>true</tt> is returned.
197     * <p>If the current thread:
198     * <ul>
199     * <li>has its interrupted status set on entry to this method; or
200     * <li>is {@link Thread#interrupt interrupted} while waiting to acquire
201     * a permit,
202     * </ul>
203     * then {@link InterruptedException} is thrown and the current thread's
204     * interrupted status is cleared.
205     * <p>If the specified waiting time elapses then the value <tt>false</tt>
206     * is returned.
207     * The given waiting time is a best-effort lower bound. If the time is
208     * less than or equal to zero, the method will not wait at all.
209     *
210     * @param timeout the maximum time to wait for a permit
211     * @param granularity the time unit of the <tt>timeout</tt> argument.
212     * @return <tt>true</tt> if a permit was acquired and <tt>false</tt>
213     * if the waiting time elapsed before a permit was acquired.
214     *
215     * @throws InterruptedException if the current thread is interrupted
216     *
217     * @see Thread#interrupt
218     *
219     */
220     public boolean tryAcquire(long timeout, TimeUnit granularity)
221     throws InterruptedException {
222     return false;
223     }
224    
225     /**
226     * Releases a permit, returning it to the semaphore.
227     * <p>Releases a permit, increasing the number of available permits
228     * by one.
229     * If any threads are blocking trying to acquire a permit, then one
230     * is selected and given the permit that was just released.
231     * That thread is re-enabled for thread scheduling purposes.
232     * <p>There is no requirement that a thread that releases a permit must
233     * have acquired that permit by calling {@link #acquire}.
234     * Correct usage of a semaphore is established by programming convention
235     * in the application.
236     */
237     public void release() {}
238    
239     /**
240     * Return the current number of permits available in this semaphore.
241     * <p>This method is typically used for debugging and testing purposes.
242     * @return the number of permits available in this semaphore.
243     */
244     public long availablePermits() {
245     return permits;
246     }
247     }
248    
249    
250