Skip to content

Commit df3e271

Browse files
committed
Add TimedSemaphore.builder() and Builder
1 parent 1441ba9 commit df3e271

File tree

3 files changed

+130
-69
lines changed

3 files changed

+130
-69
lines changed

src/changes/changes.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ The <action> type attribute can be add,update,fix,remove.
5959
<action type="add" dev="ggregory" due-to="Gary Gregory">Add JavaVersion.JAVA_25.</action>
6060
<action type="add" dev="ggregory" due-to="Gary Gregory">Add SystemUtils.IS_JAVA_25.</action>
6161
<action type="add" dev="ggregory" due-to="jack5505, Gary Gregory">Add MutablePair.ofNonNull(Map.Entry).</action>
62+
<action type="add" dev="ggregory" due-to="Gary Gregory">Add TimedSemaphore.builder() and Builder.</action>
6263
<!-- UPDATE -->
6364
<action type="update" dev="ggregory" due-to="Gary Gregory">Bump org.apache.commons:commons-parent from 88 to 89.</action>
6465
</release>

src/main/java/org/apache/commons/lang3/concurrent/TimedSemaphore.java

Lines changed: 99 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.util.concurrent.ScheduledFuture;
2222
import java.util.concurrent.ScheduledThreadPoolExecutor;
2323
import java.util.concurrent.TimeUnit;
24+
import java.util.function.Supplier;
2425

2526
import org.apache.commons.lang3.Validate;
2627

@@ -111,6 +112,75 @@
111112
*/
112113
public class TimedSemaphore {
113114

115+
/**
116+
* Builds new {@link TimedSemaphore}.
117+
*
118+
* @since 3.20.0
119+
*/
120+
public static class Builder implements Supplier<TimedSemaphore> {
121+
122+
private ScheduledExecutorService service;
123+
private long period;
124+
private TimeUnit timeUnit;
125+
private int limit;
126+
127+
/**
128+
* Constructs a new Builder.
129+
*/
130+
public Builder() {
131+
// empty
132+
}
133+
134+
@Override
135+
public TimedSemaphore get() {
136+
return new TimedSemaphore(this);
137+
}
138+
139+
/**
140+
* Sets the limit.
141+
*
142+
* @param limit The limit.
143+
* @return {@code this} instance.
144+
*/
145+
public Builder setLimit(final int limit) {
146+
this.limit = limit;
147+
return this;
148+
}
149+
150+
/**
151+
* Sets the time period.
152+
*
153+
* @param period The time period.
154+
* @return {@code this} instance.
155+
*/
156+
public Builder setPeriod(final long period) {
157+
this.period = period;
158+
return this;
159+
}
160+
161+
/**
162+
* Sets the executor service.
163+
*
164+
* @param service The executor service.
165+
* @return {@code this} instance.
166+
*/
167+
public Builder setService(final ScheduledExecutorService service) {
168+
this.service = service;
169+
return this;
170+
}
171+
172+
/**
173+
* Sets the time unit for the period.
174+
*
175+
* @param timeUnit The time unit for the period.
176+
* @return {@code this} instance.
177+
*/
178+
public Builder setTimeUnit(final TimeUnit timeUnit) {
179+
this.timeUnit = timeUnit;
180+
return this;
181+
}
182+
}
183+
114184
/**
115185
* Constant for a value representing no limit. If the limit is set to a value less or equal this constant, the {@link TimedSemaphore} will be effectively
116186
* switched off.
@@ -120,10 +190,20 @@ public class TimedSemaphore {
120190
/** Constant for the thread pool size for the executor. */
121191
private static final int THREAD_POOL_SIZE = 1;
122192

193+
/**
194+
* Constructs a new Builder.
195+
*
196+
* @return a new Builder.
197+
* @since 3.20.0
198+
*/
199+
public static Builder builder() {
200+
return new Builder();
201+
}
202+
123203
/** The executor service for managing the timer thread. */
124204
private final ScheduledExecutorService executorService;
125205

126-
/** Stores the period for this timed semaphore. */
206+
/** The period for this timed semaphore. */
127207
private final long period;
128208

129209
/** The time unit for the period. */
@@ -155,6 +235,23 @@ public class TimedSemaphore {
155235
/** A flag whether shutdown() was called. */
156236
private boolean shutdown; // @GuardedBy("this")
157237

238+
private TimedSemaphore(final Builder builder) {
239+
Validate.inclusiveBetween(1, Long.MAX_VALUE, builder.period, "Time period must be greater than 0.");
240+
period = builder.period;
241+
unit = builder.timeUnit;
242+
if (builder.service != null) {
243+
executorService = builder.service;
244+
ownExecutor = false;
245+
} else {
246+
final ScheduledThreadPoolExecutor stpe = new ScheduledThreadPoolExecutor(THREAD_POOL_SIZE);
247+
stpe.setContinueExistingPeriodicTasksAfterShutdownPolicy(false);
248+
stpe.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
249+
executorService = stpe;
250+
ownExecutor = true;
251+
}
252+
setLimit(builder.limit);
253+
}
254+
158255
/**
159256
* Constructs a new instance of {@link TimedSemaphore} and initializes it with the given time period and the limit.
160257
*
@@ -178,20 +275,7 @@ public TimedSemaphore(final long timePeriod, final TimeUnit timeUnit, final int
178275
* @throws IllegalArgumentException if the period is less or equals 0.
179276
*/
180277
public TimedSemaphore(final ScheduledExecutorService service, final long timePeriod, final TimeUnit timeUnit, final int limit) {
181-
Validate.inclusiveBetween(1, Long.MAX_VALUE, timePeriod, "Time period must be greater than 0!");
182-
period = timePeriod;
183-
unit = timeUnit;
184-
if (service != null) {
185-
executorService = service;
186-
ownExecutor = false;
187-
} else {
188-
final ScheduledThreadPoolExecutor s = new ScheduledThreadPoolExecutor(THREAD_POOL_SIZE);
189-
s.setContinueExistingPeriodicTasksAfterShutdownPolicy(false);
190-
s.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
191-
executorService = s;
192-
ownExecutor = true;
193-
}
194-
setLimit(limit);
278+
this(builder().setService(service).setPeriod(timePeriod).setTimeUnit(timeUnit).setLimit(limit));
195279
}
196280

197281
/**

0 commit comments

Comments
 (0)