当前位置: 首页 > 知识库问答 >
问题:

Java CHM 同步

平元明
2023-03-14

跟进这个问题(Java线程安全-多原子操作?),我不想再增加更多的问题,但现在我有一个疑问:

private final Map<String, Set<String>> data = Maps.newConcurrentMap();

... then in a method ...

if (data.containsKey("A")) {
    data.get("A").add("B");
}

应该是这样的:

synchronized(data) {
    if (data.containsKey("A")) {
        data.get("A").add("B");
    }
}

为了保证线程安全。对吗?

所以操作是原子的,但将它们组合起来需要同步,对吗?在这一点上,只使用简单的 HashMap 而不是并发 HashMap 是否有意义,因为我们手动处理同步?

CHM中是否有任何方法可以原子地使其工作?

共有2个答案

阎咏思
2023-03-14
匿名用户

synchronised(data) {
    if (data.containsKey("A")) {
        data.get("A").add("B");
    }
}

你可能需要展示更多的代码。

仅从这一点来看,唯一可能的问题是,在您进行< code>if检查后,有人移除了在< code >“A”找到的集合。如果你从来没有删除映射条目,你根本不需要同步

如果同时删除映射条目,则可以使用 computeIfPresent 到达更新的映射。

你也可以做

Set<String> set = data.get("A");
if (set != null) set.add("B");

由于您实际上并没有生成一个新的Set,我发现这比computeIfPresent(它应该计算一个新值)更惯用。

请注意,您还需要使所有这些 Set 成为线程安全的。

陈和裕
2023-03-14

在您的特定情况下,您可能希望使用Con

data.computeIfPresent("A", (k, v) -> { v.add("B"); return v; } );

来自javadocs:

如果指定键的值存在,则在给定该键及其当前映射值的情况下,尝试计算新的映射。整个方法调用是自动执行的。

所以不需要显式同步。

 类似资料:
  • 您可以通过 Bluetooth 连接以无线方式将数据从 Verity Sense 传输到 Polar Flow 应用。或者,您可以使用 USB 端口和 FlowSync 软件,将 Verity Sense 与 Polar Flow 网络服务同步。若要在 Verity Sense 与 Polar Flow 应用之间同步数据,您需要拥有 Polar 账户。如果您想要将 Verity Sense 上的数

  • EasyReact 是允许环形连接的,环形的连接使得多个节点可以进行同步。下面介绍关于同步的操作。 syncWith 针对于两个节点的同步,syncWith可以快速的帮我们建立两个节点的同步连接: EZRMutableNode<NSNumber *> *nodeA = [EZRMutableNode new]; EZRMutableNode<NSNumber *> *nodeB = [EZRMut

  • 要在 M600 的 Polar 应用程式、Polar Flow 移动应用程式以及 Polar Flow 网络服务之间同步数据,您需要拥有 Polar 账户。如您完成M600 的设置,则您已创建了一个账户。 自动同步训练数据 在您完成一次训练后,M600 上的 Polar 应用程式自动将您的训练及活动数据与 Polar Flow 应用程式同步。若要使用自动同步功能,您需要使用您的 Polar 账户登

  • 您可以通过 USB 端口与 FlowSync 软件或通过 Bluetooth Smart® 无线方式与 Flow 程序传输来自 A300 的数据。如要在 A300 与 Flow 网络服务和程序之间同步数据,您需要拥有 Polar 账户与 FlowSync 软件。如果您在 flow.polar.com/start中设置了 A300,说明您已创建了该账户并下载了该软件。当您开始使用 A300 时,您进

  • 请看下面给我带来麻烦的方法: 然后是run方法:

  • 我试图理解java中同步块的概念。根据我读过的文档,我明白如果我们获取一个锁(使用实例变量的同步块),那么我们就不能在该类中的同一对象上获取同步锁。但是当我尝试实际使用以下片段时,我发现我的理解出了问题。 即我能够同时以两种不同的方法获取锁(同一实例变量上的同步块)。当线程启动时,它将转到run方法并无限期地等待,并且不会从同步块中出来。同时,如果我使用相同的线程调用stop方法,它会进入同步块并

  • 我在阅读oracle的多线程官方教程时,遇到了这个例子(假设< code>c1和< code>c2从未一起使用): 据说通过使用锁1 然而,我并不认为这有助于减少阻塞,因为它们彼此之间没有依赖关系。我有多个线程同时运行这两个方法,当我使用lock对象和this关键字时,性能非常相似。 有人可以帮助解释我的困惑吗?喜欢用一个例子来说明差异。 除了这里的讨论,这篇文章也帮助澄清了我的疑虑。要点:将sy

  • 问题内容: 我面临有关Java方法同步的问题。希望我能简要解释一下: 我在两个不同的类中,在两个不同的包中有两个不同的方法。就像是: 好的,所以现在我需要同步这两个 不是thread的方法 。到目前为止,我有两种不同的方法: 共享信号量 。 在和外部创建一个共享的静态信号量,例如: 无论如何,我真的不知道JVM是否会将其视为共享信号量。 已同步(SharedClass.class) 。 使用共享类