Java:一种延迟时间的队列,可进行去重处理。

6
大家好,
我有一个系统(源)需要在某些对象更改时异步通知另一个系统(目标)。问题在于,源系统可能会在短时间内多次更改单个对象(更新非常“突发”),这种情况下最理想的是只通知一次目标系统,并且使用对象的最终状态。
我的想法是在ThreadPoolExecutor前面使用一种延迟时间和去重的队列来完成。该队列应该:
1. 将项目保留在队列中的最短时间(理想情况下配置为比典型突发变化持续时间稍微长一点)。 2. 如果出现已排队的重复项(由对象标识符定义),则替换现有对象。但是,该项应保留其原始位置在队列中(以避免任何一个项目永久被推到队列的后面-在某个时刻,即使另一个项目即将到来,我们也需要发送通知)。
我没有在java.util中找到类似的东西,而且我在这个领域的谷歌搜索似乎特别弱。
是否有人之前实施过这个功能,是否知道一个行为方式类似的BlockingQueue实现,或者有关如何实现这个功能的提示?
提前感谢!
彼得
PS。我知道ESB可以做这种事情,但在这种情况下,这太重了-理想情况下,我不想在源系统中添加任何新的库依赖项。
2个回答

4
我认为最好的方法是扩展ArrayBlockingQueue并重写offerpoll方法以添加时间延迟功能。特别是ArrayBlockingQueue因为它有一个contains方法。
另一个想法是使用DelayQueue,在其中重写offer方法以删除旧元素并插入新元素,但保留旧的时间延迟,这将基本上保留顺序。然后,您需要在Delayed接口中包装队列项。

谢谢trutheality。你有想法直接实现BlockingQueue并委托给内部的ArrayBlockingQueue实例,同时在offerpoll方法中添加一些额外逻辑吗?我总是对扩展核心JDK类感到有点谨慎-其中许多类并不是为此而设计的(特别是在java.util.concurrent中,在我的有限探索中)。 - Peter
在这种情况下,扩展和实现+内部的区别在于使用this/supermyBlockingQueue作为队列对象,因此这是一个品味问题。 - trutheality
现在我想起来了,DelayQueue 的想法可能更容易实现。我认为最棘手的部分将是在队列中更新元素,如果您使用 ArrayBlockingQueue,可能需要使用 iterator 进入其中或保留类似于引用的 ArrayList 以便轻松访问对象。使用 DelayQueue 只需 remove、匹配到期时间和 offer 即可。 - trutheality

0
你可以通知系统发生了变化,让另一个系统获取新状态。然后在状态被获取之前不再通知进一步的更改。

谢谢你的建议,Software Monkey。但我认为这会将原始问题转化为更大的问题——即需要跟踪可能数百万个对象的各个“检索状态”。 - Peter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接