java - 周期性任务取消和完成时的回调

标签 java

我有两个任务:第一个任务 (work) 是重复发生的,第二个任务 (cleanup) 是释放一些资源。 cleanup 任务应在重复出现的 work 任务完成后恰好运行一次,并且不会再次运行。

我的第一直觉是这样的:

ScheduledExecutorService service = ...;
ScheduledFuture<?> future = service.scheduleAtFixedRate(work, ...);

// other stuff happens

future.cancel(false);
cleanup.run();

这里的问题是 cancel() 立即返回。因此,如果 work 恰好正在运行,则 cleanup 将覆盖它。

理想情况下,我会使用像 Guava 的 Futures.addCallback(ListenableFuture future, FutureCallback callback) 这样的东西。 ( Guava 15 可能有 something like that )。

与此同时,当 future 被取消并且 work 不再运行时如何触发回调?

最佳答案

这是我提出的解决方案。它看起来很简单,但我仍然认为那里有更常见和/或更优雅的解决方案。我真的很想在像 Guava 这样的图书馆里看到一个......

首先我创建了一个包装器来对我的 Runnables 施加互斥:

private static final class SynchronizedRunnable implements Runnable {
    private final Object monitor;
    private final Runnable delegate;

    private SynchronizedRunnable(Object monitor, Runnable delegate) {
        this.monitor = monitor;
        this.delegate = delegate;
    }

    @Override
    public void run() {
        synchronized (monitor) {
            delegate.run();
        }
    }
}

然后我创建一个包装器以在成功调用 cancel 时触发我的回调:

private static final class FutureWithCancelCallback<V> extends ForwardingFuture.SimpleForwardingFuture<V> {

    private final Runnable callback;

    private FutureWithCancelCallback(Future<V> delegate, Runnable callback) {
        super(delegate);
        this.callback = callback;
    }

    @Override
    public boolean cancel(boolean mayInterruptIfRunning) {
            boolean cancelled = super.cancel(mayInterruptIfRunning);
            if (cancelled) {
                callback.run();
            }
            return cancelled;
    }
}

然后我用我自己的方法将它们整合在一起:

private Future<?> scheduleWithFixedDelayAndCallback(ScheduledExecutorService service, Runnable work, long initialDelay, long delay, TimeUnit unit, Runnable cleanup) {

    Object monitor = new Object();

    Runnable monitoredWork = new SynchronizedRunnable(monitor, work);

    Runnable monitoredCleanup = new SynchronizedRunnable(monitor, cleanup);

    Future<?> rawFuture = service.scheduleAtFixedRate(monitoredWork, initialDelay, delay, unit);

    Future<?> wrappedFuture = new FutureWithCancelCallback(rawFuture, monitoredCleanup);

    return wrappedFuture;
}

关于java - 周期性任务取消和完成时的回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15794792/

相关文章:

java - 如何用java解决selenium webdriver中的 "Method readfile requires 3 parameters but 0 were supplied in the @Test annotation."

java - 从父类访问子类是否被视为反模式

java - 以声明方式将 JavaObject 映射到 Javabean

java - 类加载器 + 模块 = 测试难题

java - 为什么 '#' 、 '.' 、 ':' 不能在标识符中使用?

java属性hashmap读取

java - 降级java版本

java - 如何向假客户端添加请求拦截器?

java - 在类中测试序列化方法的正确方法如何?

java - 队列的数组实现