假设我正在使用以下回调 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));
DecoratorCallback
的 run()
看起来像这样:
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/