线程安全地循环遍历 ConcurrentHashMap 而不会阻塞

Thread safely loop through ConcurrentHashMap with no blocking

我正在开发一个超低延迟和高性能的应用程序。 核心是单线程的,不用担心并发问题。

我正在开发一个计划日志功能,它会定期记录消息以防止相同的消息在日志中刷新。

因此日志 class 包含一个 ConcurrentHashMap,一个线程更新它(放置新键或更新现有值),另一个线程定期循环映射以记录所有消息。

我担心的是,当循环遍历 Map 时需要记录,这可能需要一些时间,它会阻止尝试更新 Map 的线程吗?任何阻塞都是不可接受的,因为我们的应用程序核心是单线程的。

除了 ConcurrentHashMap 之外还有其他数据结构可以用来减少内存占用吗?

有没有一种线程安全的方法可以在只读的情况下迭代 Map 而不会阻塞?即使迭代的数据可能过时仍然可以接受。

根据the java API docs,它说:

[...] even though all operations are thread-safe, retrieval operations do not entail locking [...]

此外,entrySet() 方法文档告诉我们:

The [returned] set is backed by the map, so changes to the map are reflected in the set, and vice-versa.

这意味着在对其进行迭代时可以修改地图,这意味着它确实不会阻塞整个地图。

可能还有其他结构可以让您减少内存占用、减少延迟,并可能提供更统一和一致的性能配置文件。

其中之一是工作模式,您的主要工作人员发布到一个非阻塞队列,而记录器从该队列中提取数据。这应该分离两个进程,允许多个并发发布者并允许您扩展记录器。

一个可能的数据结构是ConcurrentLinked Queue。我对 Java 的经验很少,所以我不确定它的性能配置文件与并发 hashmap 有何不同;但这是分布式系统和 golang 中非常常见的模式。