gpt4 book ai didi

java - 此类中引用的 Map 是否安全发布?

转载 作者:行者123 更新时间:2023-12-01 11:06:24 24 4
gpt4 key购买 nike

调用 IsItThreadsafe.getValue(...) 的线程是否会从变量 IsItThreadsafe.map 引用的 Map 中获取最新值(假设IsItThreadSafe.main(...) 中实现的确切使用场景?

public class IsItThreadSafe {

private Map<String, String> map;

public synchronized void setMap(Map<String, String> map) {
this.map = map;
}

public synchronized String getValue(String key) {
if (this.map == null) {
this.map = new HashMap<>();
}
return map.get(key);
}


public static void main(String[] args) throws Exception {
IsItThreadSafe sharedObject = new IsItThreadSafe();
Thread t1 = new Thread(() -> {
while (true) {
for (int i = 0; i < 10; i++) {
String key = String.valueOf(i);
String value = sharedObject.getValue(key);

if (value!=null) {
System.out.println("key = " + key + " value = " + value);
}
}
}
});
t1.start();

Thread t2 = new Thread(() -> {
while (true) {
Map<String, String> mappedData = new HashMap<>();

for (int i = 0; i < 10; i++) {
mappedData.put(String.valueOf(i), String.valueOf(i + 1));
}

sharedObject.setMap(mappedData);
}
});
t2.start();

t1.join();
t2.join();
}
}

最佳答案

似乎它应该正常工作,除非 setMap 调用者继续修改它传递给 setMap 的 map 。一旦调用setMap,它就应该忘记这个映射。一般来说,这样的版本会更安全:

public synchronized void setMap(Map<String, String> map) {
this.map = new HashMap<>(map);
}

当然,虽然你的代码是正确的,但这并不意味着代码是最优的。特别是如果您不打算将新值放入映射中,则每次查询该值时都可以取消同步。例如,您可以使用AtomicReference:

private final AtomicReference<Map<String, String>> map = new AtomicReference<>(); 

public void setMap(Map<String, String> map) {
this.map.set(new HashMap<>(map));
}

public String getValue(String key) {
Map<String, String> m = this.map.get();
// loop is necessary if setMap(null) call occurs
while (m == null) {
// Use CAS to avoid possible overwrite of concurrent setMap() call
m = new HashMap<>();
if(!this.map.compareAndSet(null, m))
m = this.map.get();
}
return m.get(key);
}

这里同步被替换为 volatile 读取,这通常要快得多。

关于java - 此类中引用的 Map 是否安全发布?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32903111/

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