作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个 java 线程安全映射,它存储字符串到对象的映射:
ConcurrentHashMap<String, MyObject> map = new ConcurrentHashMap<>();
这里的 MyObject 是一个用户定义的类。现在考虑以下方法:
public void replace(String key, MyObject o) {
MyObject m = map.get("somekey");
synchronized(m) {
// Modify some internal components of m
// and some other objects related to m
}
}
我的意图是通过不锁定整个类而只锁定试图访问映射中相同键的线程来最大化性能。基本上每次在映射中替换(未添加)条目时,都会执行这部分代码。像这样的东西:
public void put(String key, MyObject o) {
if (map.putIfAbsent(key, o) == null){ //do something
}
else {
replace(key, o);
}
}
出于所有实际目的,我们可以假设这是唯一可以更改对 MyObject 的引用的方法。这个实现线程安全吗?
最佳答案
Is the following implementation thread safe?
这取决于您如何访问和修改 MyObject
的实例在您的代码中,如果您总是访问和修改 MyObject
的给定实例在同步块(synchronized block)中使用此 MyObject
实例作为对象的监视器然后是的它将是线程安全的,否则它不会。
你的 put
方法不是线程安全的作为putIfAbsent
和 replace
未原子执行,这可能导致竞争条件问题,使用 merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction)
做完全相同的事情,但 原子地 如下:
public void put(String key, MyObject o) {
map.merge(
key, o,
(v1, v2) -> {
// Modify some internal components of v1
// and some other objects related to v1
return v2;
}
);
}
关于java - 以下实现线程安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40377773/
我是一名优秀的程序员,十分优秀!