【问题标题】:Java: a time-delayed queue that de-dupesJava:重复数据删除的延时队列
【发布时间】:2011-05-29 06:08:35
【问题描述】:

大家好,

我有一个系统(源)需要在某些对象发生变化时异步通知另一个系统(目标)。扭曲之处在于,源系统可能会在很短的时间间隔内多次改变单个对象(更新非常“突发”),在这种情况下,最好只通知目标系统一次,并以最终状态对象。

我的想法是为此在 ThreadPoolExecutor 前面使用某种延时、重复数据删除队列。该队列将:

  1. 将项目保留在队列中的时间最短(理想情况下,配置为比典型突变爆发的持续时间长一点点)

  2. 如果重复(由对象的标识符定义)入队,则替换现有对象。但是,该项目应该保留其在队列中的原始位置(以避免任何一个项目永远被撞到队列的后面 - 在某些时候我们只需要发送通知,即使另一个项目会暂时出现)。

我还没有在java.util中看到过类似的东西,而且我在这方面的google-fu似乎特别弱。

以前有没有人实现过这个,知道以这种方式运行的 BlockingQueue 实现,或者有关于如何实现它的提示?

提前致谢!

彼得

附言。我知道 ESB 会做这种事情,但在这种情况下,这种方法过于重量级了——理想情况下,我根本不想向源系统添加任何新的库依赖项。

【问题讨论】:

    标签: java concurrency queue timedelay deduplication


    【解决方案1】:

    我认为最好的办法是扩展 ArrayBlockingQueue 并覆盖 offerpoll 以添加时间延迟功能。 特别是ArrayBlockingQueue,因为它有一个contains 方法。

    另一个想法是 DelayQueue 覆盖 offer 以删除旧元素并插入新元素但保留旧的时间延迟,这将基本上保持秩序。 然后你需要将你的队列项包装在一个Delayed 接口中。

    【讨论】:

    • 感谢真实。关于直接实现BlockingQueue,但委派给内部ArrayBlockingQueue 实例,在offerpoll 方法中有一些额外逻辑的想法?我总是对扩展核心 JDK 类持怀疑态度——它们中的许多类在设计时并没有考虑到这一点(尤其是在 java.util.concurrent 中,因为我有限地在那里闲逛)。
    • 好吧,在这种情况下,扩展和实现+内部的区别在于使用 this/supermyBlockingQueue 作为队列对象之间的区别,所以这是 IMO 的品味问题。
    • 现在我想起来了,DelayQueue 的想法可能更容易。我认为最棘手的部分是在队列中更新队列元素,如果您使用ArrayBlockingQueue,则可能涉及使用iterator 进入那里或保留类似@ 的内容987654339@ 的引用,便于访问对象。对于DelayQueue,它只是remove,匹配过期时间和offer
    【解决方案2】:

    您可以只通知系统发生了更改,并让其他系统获取新状态。然后在获取状态之前不要通知进一步的更改。

    【讨论】:

    • 感谢 Software Monkey,但我认为这会将原始问题转化为更大的问题 - 即必须跟踪可能数百万个对象的各个“检索状态”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-11
    • 1970-01-01
    • 2019-02-16
    • 2017-02-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多