gpt4 book ai didi

java - 如何在 Java 中创建线程安全的一次写入多次读取 Map?

转载 作者:搜寻专家 更新时间:2023-11-01 02:30:41 25 4
gpt4 key购买 nike

我有一个带有私有(private)静态映射的 Java 类,用于在应用程序执行期间存储信息。我只会将一个键/值放入 map 中一次,但 map 值可能会被读取多次。

所以我现在的方式是,代码执行 get 并检查是否为 null。如果为 null,那么我会收集我需要的数据并将其放入 map 中。客户端代码的后续调用将保证从 map 中获取值。客户端不需要进行空值检查。

这样做的原因是将数据放入 map 可能很昂贵,所以我只想为每个键执行一次。

这有什么模式吗?我似乎找不到任何讨论这种情况的东西。

TIA

这是一个完全非线程安全的例子:

public class TestWorm {

private static Map<String, Object> map = new HashMap<String, Object>(32);

public Object getValue(String key) {
if (map.get(key) != null) {
return map.get(key);
}

// do some process to get Object
Object o = new Object();
map.put(key, o);
return o;
}
}

最佳答案

最好的选择是 ConcurrentHashMap,它是 putIfAbsent 方法。

您的实现不是线程安全的。为了使其线程安全,将字段声明为 final,将实现类更改为 ConcurrentHashMap 就足够了,如果您不关心有时是否会多次计算和存储值(这种情况很少见:如果两个线程同时输入 get 和尚未计算相应的值。这通常是一个很好的权衡,因为通常最常见的情况是缓存中有某些内容。在这种情况下,您不使用任何额外的同步来检索现有值。)

如果您想确保给定键在您的应用程序中最多存在一个值,您可以使用 putIfAbsent 来进一步扩展您的实现,而不是 put。

另一种实现方法是使用 guava 库:http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/MapMaker.html

另一种方法是使用 ConcurrentHashMapV8 的 computeIfAbsent (http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166e/ConcurrentHashMapV8.java?view=markup ) 总有一天会出现在 Java 8 中。

关于java - 如何在 Java 中创建线程安全的一次写入多次读取 Map?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10152726/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com