【问题标题】:Concurrent map sorted by values with fast increment value operation快速递增值操作按值排序的并发映射
【发布时间】:2010-09-28 13:28:06
【问题描述】:

我有一个网络应用程序,我需要在其中跟踪“最受欢迎”(访问量最大的)文章。该应用程序中的大多数页面(包括文章页面)在侧边栏中显示“最受欢迎”列表,因此该列表将被经常检索。另一方面,文章也经常被访问(大约 1/2 的页面访问是对文章页面的访问)。

跟踪访问并能够选择 N 个访问次数最多的文章的最佳方法是什么?据我了解,它应该是一个并发地图 articleId->visitCount,它按值 (visitCounts) 排序,我可以在其中快速(和线程安全地)递增 visitCount 并期望地图自行重新排序。

【问题讨论】:

    标签: java data-structures concurrency


    【解决方案1】:

    对于 Web 应用程序,存储它的最佳位置是在数据库中。创建一个数据库,其中包含文章 ID 字段和访问次数字段。按访问次数索引表。每当查看文章时,添加记录或增加现有记录。当您需要查看最受欢迎的列表时,只需查询该表即可。

    数据库通常是在 Web 应用程序中将数据存储在何处的最佳答案。

    在这种情况下,数据库将根据访问次数对表进行索引。这使得插入和更新速度有点慢,但是数据库被设计为完成这项工作,所以它不会太糟糕。由于维护的索引,这些数据的检索总是非常快。

    【讨论】:

    • 如果文章同时被 1K 用户访问怎么办。这不会因为计数增量上的行锁定而导致连接超时吗?
    【解决方案2】:

    如果您不想使用数据库,则可以使用SortedSet 来存储同时包含文章 ID 和访问次数的对象。对象的比较将是访问计数。实现可以包括TreeSet,它必须在多线程环境中进行外部同步,以及ConcurrentSkipListSet,它不必进行外部同步。

    【讨论】:

    • 大多数 SortedSet 实例,其中元素的比较不具有传递性(因为被比较的对象发生了变化)会导致一些非常奇怪的错误。您将如何处理 a > b > a ???
    【解决方案3】:

    就个人而言,我不会在更新期间尝试回答这个问题。与阅读相比,您每次访问都更有可能更新您的结构。

    当需要阅读时,复制每个 id,visit# 条目,然后对其进行排序以进行显示。你会惊讶于它有多便宜。

    【讨论】:

    • 可能有超过一百万篇文章,因此不幸的是,不能每次都对它们进行排序。
    猜你喜欢
    • 1970-01-01
    • 2021-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-29
    • 2022-01-10
    • 1970-01-01
    • 2013-08-12
    相关资源
    最近更新 更多