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, 1 month 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

# Content
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