public void updatePrice(Price update){
sendPriceUpdate(update); //takes a long time
}
我想构建一个将执行上述操作的类,除非 sendPriceUpdate 调用仍在运行,它会等待并将挂起的更新排队。一旦调用返回,它将发送最后一次更新(并丢弃其他更新)。即等待发送调用返回,然后发送最后一个挂起的价格更新。
使用什么合适的数据结构?
public void updatePrice(Price update){
sendPriceUpdate(update); //takes a long time
}
我想构建一个将执行上述操作的类,除非 sendPriceUpdate 调用仍在运行,它会等待并将挂起的更新排队。一旦调用返回,它将发送最后一次更新(并丢弃其他更新)。即等待发送调用返回,然后发送最后一个挂起的价格更新。
使用什么合适的数据结构?
最好的解决方案是更新已经知道这一点,并且只获取“增量”数据,即已更改或仅存在差异的数据。如果这不可能,那么您别无选择,只能回滚最新更新。为此,您需要存储以前的更新,以便您可以撤消它并推送新的更新。像这样的东西应该工作:
public class Updater
{
private static Price prevUpdate = null;
public static synchronized void updatePrice(Price update)
{
if (prevUpdate != null)
{
rollbackUpdate(prevUpdate);
}
sendPriceUpdate(update); //takes a long time
prevUpdate = update;
}
}
我已将其更改为,static
因为我认为您不需要实例化此类的对象。对我来说看起来像是一个静态服务。如果我错了(例如不同的线程想要使用不同的更新程序,从而跟踪不同的更新),请更改它。
这是线程安全的,但是如果sendPriceUpdate()
需要很长时间,它会在updatePrice()
方法上锁定很多线程。这也不考虑抛出任何异常,您应该考虑到这一点。
正如我在评论中所说,恕我直言,这是一个(非常?)糟糕的解决方案,但如果您不知道哪个是最后一个或最后一个何时到来,这是唯一的。软件重新设计可能会解决这种情况,或者在更高级别解决它(在调用之前updatePrice()
)
我建议您使用 Active-Object 模式 - 您应该将队列(AKA Activation-queue 或操作队列)与您的对象相关联。我将首先解释如何在不丢弃的情况下解决,然后解释我认为丢弃应该如何处理。主要思想如下:
A. 你的对象将有一个队列的字段 - 假设一个通用类型的 Queue(具有 PriceOperation 的通用参数)
B. PriceOperation 将持有一个方法对象(java.lang.reflect.method) ,调用的目标对象 - 让我们的 PriceManager(它具有 updatePrice 方法)和参数(假设更新它应该是价格)
C. sendPriceUpdate 将使用“update”的方法对象(假设 Price 有这样的方法)或在同步调用的情况下您将激活的方法的方法对象排入队列和 PriceOperation 的对象
D. 与相关联的线程该对象将在队列中等待,当队列不为空时,它将出列一个 PriceOperation 对象,并使用相关参数(Price 对象)调用目标对象(无论是 PriceManager 还是其他)上的方法
E. 这样,您将能够保持等待更新的队列,并且仍然与您的 PriceManager 异步工作
F. 我刚刚注意到您有兴趣放弃最后的更新 - 如果是这种情况,那么您应该适当地使用优先级队列,而不是队列,并根据时间戳进行优先级排序,这样 PriceOperation最近创建的将被处理。您需要在生产者(PriceManager)和消费者(线程)之间同步这个队列。