【问题标题】:Efficiently update an element in a DelayQueue有效地更新延迟队列中的元素
【发布时间】:2015-01-14 17:26:43
【问题描述】:

我面临与作者类似的问题: DelayQueue with higher speed remove()?

问题: 我需要处理不断传入的数据,并检查数据是否已经在某个时间范围内看到过。因此,我计算传入数据的唯一 ID,并将该 ID 索引的数据添加到地图中。同时,我将 ID 和超时时间戳存储在 PriorityQueue 中,使我能够有效地检查最新的 ID 是否超时。不幸的是,如果数据在指定的超时之前再次进入,我需要更新存储在 PriorityQueue 中的超时。到目前为止,我刚刚删除了旧 ID 并重新添加了 ID 以及新的超时。这很好用,除了如果我的 PriorityQueue 增长超过 300k 个元素时会使用耗时的 remove 方法。

可能的解决方案: 我只是考虑改用DelayQueue,这样可以更容易地等待第一个数据超时,不幸的是我还没有找到一种有效的方法来更新存储在这种DelayQueue中的超时元素,而不会遇到与使用相同的问题PriorityQueue:remove 方法!

关于如何以有效的方式解决这个问题,即使对于一个巨大的队列有什么想法吗?

【问题讨论】:

    标签: java performance queue


    【解决方案1】:

    这实际上听起来很像Guava Cache,它是一个并发的堆上缓存,支持“在最近一次查找此条目后很长时间过期”。如果您可以使用第三方库,那么重用它可能是最简单的。

    如果做不到这一点,实现使用的方法看起来像这样:它有一个哈希表,因此可以通过它们的键有效地查找条目,但这些条目也在一个并发的自定义链表中——你可以' t 使用内置库执行此操作。链表按照“最近最少访问的优先”的顺序排列。当一个条目被访问时,它被移动到链表的末尾。每隔一段时间,您就会查看列表的开头(所有最近访问最少的条目都位于该列表的开头),然后删除那些早于您的阈值的条目。

    【讨论】:

    • 感谢您的想法!我将研究番石榴缓存。在写完最初的问题后,我想到了以下想法:我不会更新队列中的超时,而是保持它们不变,只更新与数据一起存储的 Map 中的超时元素。在检索队列的头部时,我检查超时是否仍然与映射中存储的相同,如果不是,我将重新添加元素到队列中。因此,我可以避免从队列中显式删除元素,而不仅仅是使用 poll()
    猜你喜欢
    • 2015-06-11
    • 2022-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-25
    • 2013-09-27
    相关资源
    最近更新 更多