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

java - ConcurrentHashMap 多个 key 如何实现原子操作?

屈晨
2024-08-07

在使用 ConcurrentHashMap 时,ConcurentHashMap 通过 CAS 保证了操作的线程安全。但是当我们需要进行多个操作和复合操作时,ConcurentHashMap 并不能保证操作的原子性:
get 和 put 分别是线程安全的,然而当我们先 get 后 put 操作时,从 get 到 put 的过程中间,其他线程可能已经修改了这个key对应的值。
ConcurrentHashMap 通过 compute 提供了单个 key 的原子操作,然而当我们需要操作多个 key 时,compute 无法支持。
现在我的业务场景需要将多个 key 原子地写入 ConcurentHashMap,当某个key已存在时,则所有 key 均不写入。我可以怎么样尽可能高性能地实现呢?

我考虑过:

  1. 整个 map 加锁,但是这样锁的粒度太大了,性能影响太大。
  2. 对需要操作的键加锁,这就不如直接不使用ConcurrentHashMap了。

共有1个答案

何浩荡
2024-08-07

使用CopyOnWriteArraySet保存已有的keys,写ConcurentHashMap之前,先判断Set是否存在需要写入的keys,如果不存在则立刻先写Set,再写Map

 类似资料:
  • rename oldkey newkey 如果newkey存在,将会被覆盖,返回1表示成功,0失败。可能是oldkey不存在或者和newkey相同 renamenx oldkey newkey 同上,但是如果newkey存在返回失败

  • 我正在使用Memcached(使用spymemcached作为客户端)缓存从远程服务器接收的响应。我的程序逻辑很简单: 如果请求的资源缓存在Memcached,请立即返回缓存; 如果没有,请连接到远程服务器,缓存它,然后返回结果。 这个程序就像是, 但是我注意到,由于同时会有许多并发请求,有可能两个线程都发现为,因此它们都调用,这是我不希望的。 那么,我该如何避免这件事。spymemcached中

  • 我只是一个非开发人员,所以我的问题可能非常简单! 我只是在测试Java多线程的东西,这不是真正的代码。我想知道如何在 Java 中同时更新两个成员变量,以防我们希望它们都同步。举个例子: 在这种情况下(当然,想象一下多线程),我希望能够保证对< code>items和< code>itemToStatus的任何读取总是返回相同的结果。 因此,如果代码在< code>itemToStatus.put

  • 问题内容: 我想在Web Java应用程序中实现重量级对象的简单缓存。但是我不知道该怎么做。 我是否缺少某些东西或ConcurrentHashMap方法(putIfAbsent等)还不够,是否需要额外的同步? 是否有更好的简单API(在内存存储中,没有外部配置)来执行此操作? P. 问题答案: 如果为要缓存的内容临时拥有多个实例是安全的,则可以执行“无锁”缓存,如下所示: 多个线程可以“竞争”来创

  • 问题内容: 最近,我正在阅读一个教程,其中遇到了一条声明: “Java语言规范保证了读取或写入的变量是一个原子操作(除非该变量的类型的或)类型的操作变量或者是只有当它们与申报原子的关键字。” 或提供类似的方法,并且其是原子的。 我对以上声明感到有些困惑。.请您澄清一下 何时使用 或 使用类。 问题答案: 否则(与作为一个)是一个原子操作。但是执行操作不是原子操作,因为它需要读取a的值,递增和写入a

  • 主要内容:1 atomic的概述,2 原子更新单个变量,2.1 基本原子类,2.2 带版本号的原子类,3 原子更新数组,3.1 重要属性,3.2 重要方法,4 原子更新字段属性,5 原子类的加强,6 atomic的总结基于JDK1.8详细介绍了JUC下面的atomic子包中的大部分原子类的底层源码实现,比如AtomicInteger、AtomicIntegerArray、AtomicStampedReference等原子类源码。最后还介绍了JDK1.8对原子类的增强,比如LongAdder和Lo

  • python多进程共享一个可操作的变量, 如何保证原子操作? 我的需求 目前有多组数据需要执行计算型任务, 每执行完一组数据就要给java通知并传递生成的结果文件, 并且我要在把所有任务都执行完的时候(也就是最后一组数据执行完的时候)告诉java本轮次数据全部执行完毕, java那边就要去整体做数据库入库的操作。 我的设想 多进程之间维护一个整型数值, 在执行完一组数据的时候自增1, 并在通知ja

  • 我需要用Java实现一个带有Key Vault的符号,使用Sha1算法,但不被支持,如何实现呢,我尝试用bouncy castle做了de digest并用RSNULL算法使用Key Vault客户端,但结果是不正确的。 产生的输出:IOGXIIIZ5ZYM2M7OZZ/ET8UOWWTWMKESEJVVS9W9CPHZ11WKFZ/IKGX2SJ4ADHCN32QCDBOSV/KNATVPYW+