用于写密集型应用程序的Java并发集合-只有少量读取
在选择Java数据结构时,我正在寻找写密集型应用程序的各种备选方案。我知道,一个数据结构不能为一个写密集型应用程序提供单一的通用解决方案,但我很惊讶在这个主题上缺乏讨论 有很多人在谈论或应用程序,但我找不到任何关于用于写密集型应用程序的数据结构的对话 基于以下要求用于写密集型应用程序的Java并发集合-只有少量读取,java,concurrency,java.util.concurrent,Java,Concurrency,Java.util.concurrent,在选择Java数据结构时,我正在寻找写密集型应用程序的各种备选方案。我知道,一个数据结构不能为一个写密集型应用程序提供单一的通用解决方案,但我很惊讶在这个主题上缺乏讨论 有很多人在谈论或应用程序,但我找不到任何关于用于写密集型应用程序的数据结构的对话 基于以下要求 键/值对-Map 未分类-为了简单起见 每分钟1000+次写入/可忽略的读取 所有数据都存储在内存中 我正在考虑以下方法 SimpleConcurrentHashMap:尽管基于Oracle官方文档 […]即使所有操作都是线程安全的,
Map
ConcurrentHashMap
:尽管基于Oracle官方文档BlockingQueue
和一组ConcurrentHashMap
s的组合。在批处理中,队列中的所有元素都会被清空,然后在基础映射中适当地分配更新。但是,在这种方法中,我需要一个额外的映射来标识每个映射都包含哪些映射,就像一个编排器一样HashMap
并在API级别进行同步。这意味着每个与写相关的方法都将被同步synchronized void aWriteMethod(整数aKey,字符串aValue){
本书面意向书(aKey,aValue);
}
如果这个问题不仅受到上述选项的批评,而且还得到关于新的更好解决方案的建议,那就太好了
PS:除了数据的完整性、操作顺序和节流问题之外,在选择写密集型的“最佳”方法时还需要考虑哪些问题
我知道这看起来可能有点开放,但听听人们对这个问题的看法会很有趣。即使您选择最糟糕的映射类型,例如同步哈希映射,我认为您不会注意到负载对性能的任何影响。每分钟写几千封信算不了什么 我将建立一个JMH基准测试,并尝试各种map实现。显而易见的候选者是ConcurrentHashMap,因为它是为处理并发访问而设计的
因此,我认为这是一个过早优化的好例子。即使您选择最差的映射类型,例如同步HashMap,我认为您不会注意到负载对性能的任何影响。每分钟写几千封信算不了什么 我将建立一个JMH基准测试,并尝试各种map实现。显而易见的候选者是ConcurrentHashMap,因为它是为处理并发访问而设计的
因此,我认为这是一个很好的过早优化示例。用例是什么?为什么是地图?如果您有一个写密集型应用程序,并且不需要重复数据消除,那么您可以使用链表而不锁定整个结构。@BurakSerdar如果我使用映射,那么在每次更新/升级/删除时,我都需要扫描整个列表以找到我要触摸的条目。这就是为什么map看起来更合适的选择。另一点是,您需要了解插入操作的速度和算法,因为这样您就知道将使用哪种同步。例如,是否只有一个值被锁定,值的子集被锁定,或者整个集合被锁定。如果你想一想树是如何重新平衡的,我敢肯定这会带来巨大的同步开销。最后,不同的应用程序会有所不同,因此负载测试/基准测试是找到最佳替代方案的好方法。您可能更喜欢使用无锁映射,它以不支持原子计算方法为代价提供更高的写入吞吐量。否则,如果您不需要立即读取写操作,则中间队列(通过环形缓冲区)允许您廉价地记录更新,在单个线程上消耗更新,并通过追赶来惩罚读卡器。咖啡因缓存使用这种记录/重放方法,因为每次LRU读取都是一次内部写入。@Niko Yes,不过
ArrayBlockingQueue
使用锁,而JCTools提供有界无锁队列。无论采用哪种方式,都存在分片和清空队列的复杂性。正如ConcurrentHashMap在Zipfian发行版上所做的那样,16+/s的写入速率很低。您应该通过JMH进行基准测试,因为您可能对股票hashmap没有问题。用例是什么?为什么是地图?如果您有一个写密集型应用程序,并且不需要重复数据消除,那么您可以使用链表而不锁定整个结构。@BurakSerdar如果我使用映射,那么在每次更新/升级/删除时,我都需要扫描整个列表以找到我要触摸的条目。这就是为什么map看起来更合适的选择。另一点是,您需要了解插入操作的速度和算法,因为这样您就知道将使用哪种同步。例如,是否只有一个值被锁定,值的子集被锁定,或者整个集合被锁定。如果你想一想树是如何重新平衡的,我敢肯定这会带来巨大的同步开销。最后,不同的应用程序会有所不同,因此负载测试/基准测试是找到最佳替代方案的好方法。您可能更喜欢使用无锁映射,它以不支持原子计算方法为代价提供更高的写入吞吐量。否则,如果您不需要立即读取写操作,则中间队列(通过环形缓冲区)允许您廉价地记录更新,在单个线程上消耗更新,并通过追赶来惩罚读卡器。此录制/重播方法由