Skip to content

Instantly share code, notes, and snippets.

@vladimir-bukhtoyarov
Created April 23, 2016 15:54
Show Gist options
  • Save vladimir-bukhtoyarov/f5a3163d665c28794cda7fa5e024b56c to your computer and use it in GitHub Desktop.
Save vladimir-bukhtoyarov/f5a3163d665c28794cda7fa5e024b56c to your computer and use it in GitHub Desktop.
import java.lang.ref.WeakReference;
import java.util.concurrent.*;
import java.util.function.Consumer;
public class SchedulerLeakProtector {
public static <T> ScheduledFuture<?> scheduleAtFixedRate(ScheduledExecutorService scheduler, T target, Consumer<T> consumer, long initialDelay, long period, TimeUnit timeUnit) {
CompletableFuture<ScheduledFuture<?>> scheduledFutureFuture = new CompletableFuture<>();
LeakProtectedRunnable<T> runnable = new LeakProtectedRunnable<>(target, consumer, scheduledFutureFuture);
ScheduledFuture<?> scheduledFuture = scheduler.scheduleAtFixedRate(runnable, initialDelay, period, timeUnit);
scheduledFutureFuture.complete(scheduledFuture);
return scheduledFuture;
}
private static final class LeakProtectedRunnable<T> implements Runnable {
private final WeakReference<T> targetReference;
private final Consumer<T> consumer;
private final CompletableFuture<ScheduledFuture<?>> scheduledFutureFuture;
LeakProtectedRunnable(T target, Consumer<T> consumer, CompletableFuture<ScheduledFuture<?>> scheduledFutureFuture) {
this.targetReference = new WeakReference<>(target);
this.consumer = consumer;
this.scheduledFutureFuture = scheduledFutureFuture;
}
@Override
public void run() {
T target = targetReference.get();
if (target != null) {
// target object still strong referenced
consumer.accept(target);
return;
}
// target object became unreachable lets cancel scheduled task
try {
scheduledFutureFuture.get().cancel(false);
} catch (Exception e) {
throw new IllegalStateException(e);
}
}
}
}
@vladimir-bukhtoyarov
Copy link
Author

Sometimes you need to do something periodical work under object until it strongly referenced. But adding new scheduled task to executor leads to creation new strong reference, so object has no chanses to became unreachable. This utility class protect object from leak strong reference through ScheduledExecutorService.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment