java - 并发HashMap的片段,用于检索对象或创建对象(如果不存在)(作为原子操作)

标签 java java.util.concurrent concurrent-programming

在Java中,我想做这样的事情:

   Object r = map.get(t);
   if (r == null) {
      r = create(); // creating r is an expensive operation.
      map.put(t, r);  
   }

现在该代码片段可以在多线程环境中执行。 map 可以是 ConcurrentHashMap。

但是我如何使该逻辑原子化?

请不要给我像“同步” block 这样的琐碎解决方案。 我希望这个问题能够一劳永逸地得到解决。

最佳答案

Guava 巧妙地解决了这个问题.

使用CacheBuilder并调用builda CacheLoader 。这将返回 LoadingCache目的。如果您确实需要 Map 实现,您可以调用 asMap() .

还有较旧的 MapMaker及其makeComputingMap ,但这已被弃用,取而代之的是 CacheBuilder 方法。

当然,您也可以手动实现它,但正确执行此操作并非易事。需要考虑的几个方面是:

  • 您希望避免使用相同的输入调用 create 两次
  • 您想要等待当前线程完成创建,但不想使用空闲循环来完成此操作
  • 您希望避免在好的情况下进行同步(即元素已在 map 中)。
  • 如果两个 create 调用同时发生,您希望每个调用者只等待​​与他相关的调用。

关于java - 并发HashMap的片段,用于检索对象或创建对象(如果不存在)(作为原子操作),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13723372/

相关文章:

Java 从对象字段构建嵌套 HashMap

java - Rocks DB的Java API是否支持前缀扫描?

java - 如何包装 ConcurrentSkipListSet 以线程安全的方式保持最新值的固定容量?

multithreading - Condition 的哪些实现不需要当前线程持有锁?

Java:停止线程 TCP 服务器的好方法?

java - spring data是否为mongodb处理 “consistent request”?

java - 如何将弹出菜单添加到 JTextField

java - Spring MVC 3 localeChangeInterceptor

java - AbstractQueuedSynchronizer.acquireShared 无限等待,即使等待条件已经改变

java - 了解 java 执行程序服务关闭和 awaitTermination