Hello! 欢迎来到小浪资源网!


ConcurrentHashMap中如何保证多个Key的原子操作?


ConcurrentHashMap中如何保证多个Key的原子操作?

concurrenthashmap 中多个 key 原子操作的实现

在使用 concurrenthashmap 时,对单个 key 的操作是线程安全的。然而,对于跨越多个 key 的复合操作,concurrenthashmap 无法保证原子性。例如,在先 get 后 put 的过程中,其他线程可能会修改 key 对应的值。

高性能解决方案

为了在 concurrenthashmap 中实现多个 key 的原子写入,可以使用以下高性能解决方案:

  1. copyonwritearrayset 跟踪已存在的 key

使用一个 copyonwritearrayset 跟踪已存在的 key。在写入 concurrenthashmap 之前,先检查 set 中是否存在需要写入的 key。如果不存在,则先写入 set,然后再写入 concurrenthashmap。

通过这种方式,可以确保以下行为:

  • 如果某个 key 已存在,所有 key 均不会写入 concurrenthashmap。
  • 如果所有 key 都不存在,则在写入 set 和 concurrenthashmap 的过程中间,其他线程无法修改这些 key。
  1. 递归重试

如果在检查 set 和写入 concurrenthashmap 之间,其他线程修改了某些 key,则可以递归重试写入操作。这将继续直到所有 key 都成功写入或检测到至少一个 key 已存在。

代码示例

以下代码示例演示了如何使用此解决方案:

import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArraySet;  public class MultipleKeyAtomicWrite {      private static final ConcurrentHashMap<String, String> map = new ConcurrentHashMap<>();     private static final CopyOnWriteArraySet<String> existingKeys = new CopyOnWriteArraySet<>();      public static void main(String[] args) {         // 获取需要写入的 Key         Set<String> keys = new HashSet<>();         keys.add("key1");         keys.add("key2");         keys.add("key3");          // 尝试原子写入 Key         tryAtomicWrite(keys);          // 打印写入结果         System.out.println(map);     }      private static void tryAtomicWrite(Set<String> keys) {         // 检查 Set 中是否存在需要写入的 Key         for (String key : keys) {             if (existingKeys.contains(key)) {                 // 已存在某个 Key,放弃写入所有 Key                 return;             }         }          // 所有 Key 都不存在,开始写入         boolean success = true;         for (String key : keys) {             success = map.putIfAbsent(key, "value") == null & success;         }          // 如果写入失败(即存在某个 Key),递归重试         if (!success) {             tryAtomicWrite(keys);         }          // 将写入的 Key 添加到 Set 中         for (String key : keys) {             existingKeys.add(key);         }     } }

相关阅读