Allow tasks to no longer be run regularly
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import java.time.Duration;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
import java.util.Objects;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.atomic.AtomicBoolean;
public class Regularly {
private final ScheduledExecutorService executor;
+ private final List<RetryingRunnable> scheduledRunnables = new ArrayList<>();
public Regularly(String name) {
Objects.requireNonNull(name, "Name must be set");
@@ -39,18 +44,41 @@ public void submit(Runnable task, Duration successPeriod, Duration retryPeriod)
Objects.requireNonNull(successPeriod, "Success period must be set.");
Objects.requireNonNull(retryPeriod, "Retry period must be set.");
- executor.schedule(new RetryingRunnable(task, successPeriod.toMillis(), retryPeriod.toMillis()), 0, MILLISECONDS);
+ RetryingRunnable runnable = new RetryingRunnable(
+ task,
+ successPeriod.toMillis(),
+ retryPeriod.toMillis());
+
+ synchronized (scheduledRunnables) {
+ scheduledRunnables.add(runnable);
+ }
+
+ executor.schedule(runnable, 0, MILLISECONDS);
}
public void shutdown() {
executor.shutdown();
}
+ public void remove(Runnable runnable) {
+ synchronized (scheduledRunnables) {
+ Iterator<RetryingRunnable> iterator = scheduledRunnables.iterator();
+ while (iterator.hasNext()) {
+ RetryingRunnable compareWith = iterator.next();
+ if (compareWith.equals(runnable)) {
+ iterator.remove();
+ compareWith.stop();
+ }
+ }
+ }
+ }
+
private class RetryingRunnable implements Runnable {
private final Runnable delegate;
private final long successPeriod;
private final long retryPeriod;
+ private final AtomicBoolean stop = new AtomicBoolean(false);
public RetryingRunnable(Runnable delegate, long successPeriod, long retryPeriod) {
this.delegate = delegate;
@@ -60,6 +88,10 @@ public RetryingRunnable(Runnable delegate, long successPeriod, long retryPeriod)
@Override
public void run() {
+ if (stop.get()) {
+ return;
+ }
+
try {
delegate.run();
executor.schedule(this, successPeriod, MILLISECONDS);
@@ -67,5 +99,9 @@ public void run() {
executor.schedule(this, retryPeriod, MILLISECONDS);
}
}
+
+ public void stop() {
+ this.stop.set(true);
+ }
}
}
