124 |
|
private final Sync sync; |
125 |
|
|
126 |
|
/** |
127 |
< |
* Synchronization implementation for semaphore. |
128 |
< |
* Uses AQS state to represent permits |
127 |
> |
* Synchronization implementation for semaphore. Uses AQS state |
128 |
> |
* to represent permits. Subclassed into fair and nonfair |
129 |
> |
* versions. |
130 |
|
*/ |
131 |
< |
private final static class Sync extends AbstractQueuedSynchronizer { |
132 |
< |
final boolean fair; |
132 |
< |
Sync(int permits, boolean fair) { |
133 |
< |
this.fair = fair; |
131 |
> |
abstract static class Sync extends AbstractQueuedSynchronizer { |
132 |
> |
Sync(int permits) { |
133 |
|
setState(permits); |
134 |
|
} |
135 |
|
|
136 |
< |
public int getPermits() { |
136 |
> |
final int getPermits() { |
137 |
|
return getState(); |
138 |
|
} |
139 |
|
|
140 |
< |
public int tryAcquireShared(boolean isFirst, int acquires) { |
142 |
< |
if (!isFirst && fair) |
143 |
< |
return -1; |
140 |
> |
final int nonfairTryAcquireShared(int acquires) { |
141 |
|
for (;;) { |
142 |
|
int available = getState(); |
143 |
|
int remaining = available - acquires; |
147 |
|
} |
148 |
|
} |
149 |
|
|
150 |
< |
protected boolean tryReleaseShared(int releases) { |
150 |
> |
protected final boolean tryReleaseShared(int releases) { |
151 |
|
for (;;) { |
152 |
|
int p = getState(); |
153 |
|
if (compareAndSetState(p, p + releases)) |
155 |
|
} |
156 |
|
} |
157 |
|
|
158 |
< |
void reducePermits(int reductions) { |
158 |
> |
final void reducePermits(int reductions) { |
159 |
|
for (;;) { |
160 |
|
int current = getState(); |
161 |
|
int next = current - reductions; |
164 |
|
} |
165 |
|
} |
166 |
|
|
167 |
< |
int drainPermits() { |
167 |
> |
final int drainPermits() { |
168 |
|
for (;;) { |
169 |
|
int current = getState(); |
170 |
|
if (current == 0 || compareAndSetState(current, 0)) |
174 |
|
} |
175 |
|
|
176 |
|
/** |
177 |
+ |
* NonFair version |
178 |
+ |
*/ |
179 |
+ |
final static class NonfairSync extends Sync { |
180 |
+ |
NonfairSync(int permits) { |
181 |
+ |
super(permits); |
182 |
+ |
} |
183 |
+ |
|
184 |
+ |
protected int tryAcquireShared(int acquires) { |
185 |
+ |
return nonfairTryAcquireShared(acquires); |
186 |
+ |
} |
187 |
+ |
} |
188 |
+ |
|
189 |
+ |
/** |
190 |
+ |
* Fair version |
191 |
+ |
*/ |
192 |
+ |
final static class FairSync extends Sync { |
193 |
+ |
FairSync(int permits) { |
194 |
+ |
super(permits); |
195 |
+ |
} |
196 |
+ |
|
197 |
+ |
protected int tryAcquireShared(int acquires) { |
198 |
+ |
Thread current = Thread.currentThread(); |
199 |
+ |
for (;;) { |
200 |
+ |
if (!isFirst(current)) |
201 |
+ |
return -1; |
202 |
+ |
int available = getState(); |
203 |
+ |
int remaining = available - acquires; |
204 |
+ |
if (remaining < 0 || |
205 |
+ |
compareAndSetState(available, remaining)) |
206 |
+ |
return remaining; |
207 |
+ |
} |
208 |
+ |
} |
209 |
+ |
} |
210 |
+ |
|
211 |
+ |
/** |
212 |
|
* Construct a <tt>Semaphore</tt> with the given number of |
213 |
|
* permits and the given fairness setting. |
214 |
|
* @param permits the initial number of permits available. This |
218 |
|
* first-out granting of permits under contention, else false. |
219 |
|
*/ |
220 |
|
public Semaphore(int permits, boolean fair) { |
221 |
< |
sync = new Sync(permits, fair); |
221 |
> |
sync = (fair)? new FairSync(permits) : new NonfairSync(permits); |
222 |
|
} |
223 |
|
|
224 |
|
/** |
301 |
|
* otherwise. |
302 |
|
*/ |
303 |
|
public boolean tryAcquire() { |
304 |
< |
return sync.tryAcquireShared(true, 1) >= 0; |
304 |
> |
return sync.nonfairTryAcquireShared(1) >= 0; |
305 |
|
} |
306 |
|
|
307 |
|
/** |
468 |
|
*/ |
469 |
|
public boolean tryAcquire(int permits) { |
470 |
|
if (permits < 0) throw new IllegalArgumentException(); |
471 |
< |
return sync.tryAcquireShared(true, permits) >= 0; |
471 |
> |
return sync.nonfairTryAcquireShared(permits) >= 0; |
472 |
|
} |
473 |
|
|
474 |
|
/** |
594 |
|
* @return true if this semaphore has fairness set true. |
595 |
|
*/ |
596 |
|
public boolean isFair() { |
597 |
< |
return sync.fair; |
597 |
> |
return sync instanceof FairSync; |
598 |
|
} |
599 |
|
|
600 |
|
/** |