java - 如何安全地装饰现有的回调?

标签 java concurrency callback

假设我正在使用以下回调 API:

/**
 * Registers a new action which will be run at some later time on
 * some other thread, clearing any previously set callback action.
 *
 * @param callback an action to be run later.
 * @returns the previously registered action.
 */
public Runnable register(Runnable callback);

我想注册我自己的 Action ,但我想保留任何设置的行为。换句话说,我希望我的操作看起来像:

new Runnable() {
  public void run() {
    // do my work

    originalCallback.run();
  }
}

向我的 Runnable 提供 originalCallback 的最干净的方法是什么?

想到的幼稚解决方案可能会引入一个时间窗口,在该时间窗口中 originalCallback 在调用回调时不可用,或者涉及一些复杂的锁定。

最佳答案

经过更多挖掘,我发现了 Guava 的 SettableFuture和 Java 8 的 CompletableFuture .我会将我的 BlockingSupplier 留给后代使用,但这些 Future 实现中的任何一个都将更加标准,并且工作方式相同。


您基本上需要一个具有阻塞 get() 方法的持有者类。像这样:

public class BlockingSupplier<E> implements Supplier<E> {
  private final CountDownLatch latch = new CountDownLatch(1);
  private volatile E value;

  public synchronized void set(E value) {
    checkState(latch.getCount() > 0, "Cannot call set more than once.");
    this.value = value;
    latch.countDown();
  }

  @Override
  public E get() {
    latch.await(); // will block until set() is called
    return value;
  }
}

然后你可以像这样使用它:

BlockingSupplier<Runnable> supplier = new BlockingSupplier<>();
// Pass the BlockingSupplier to our callback
DecoratorCallback myAction = new DecoratorCallback(supplier);
// Register the callback, and set the BlockingSupplier to the old callback
supplier.set(register(myAction));

DecoratorCallbackrun() 看起来像这样:

public void run() {
  // do my work

  // This will block until supplier.set() returns
  originalCallbackSupplier.get().run();
}

正如 durron597 提到的,有更好的方法来设计回调 API,但考虑到问题中的 API,这似乎是合理的。

关于java - 如何安全地装饰现有的回调?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32193064/

相关文章:

c++ - 宽松的内存顺序效果是否可以延长到执行线程的生命周期之后?

java - 检查大小然后执行操作 - ConcurrentLinkedDeque 是否安全?

callback - Bokeh 按钮回调 : unexpected attribute 'callback' to Button, 中出现错误,类似的属性是 js_event_callbacks

java - 卸载 Java EE 后无法打开 Eclipse

java - 如何在 Java 中将 Unchecked Exception 转换为 Checked Exception,反之亦然

java - 如何在线程 run() 结束后立即调用方法?

c++ - 如何将函数回调传递给类成员?

java - Eclipse PDE - 如何在标准属性 View 中对属性进行排序

java - Android 和 iOS 中的文件安全

javascript - 仅在另一个脚本完成后才运行一个脚本的方法有哪些?