【发布时间】:2014-04-24 09:10:40
【问题描述】:
在我的应用程序中,我使用的是 ConcurrentHashMap,我需要这种类型的“自定义 put-if-absent”方法以原子方式执行。
public boolean putIfSameMappingNotExistingAlready(String key, String newValue) {
String value;
synchronized (concurrentHashMap) {
if (value = concurrentHashMap.putIfAbsent(key, newValue)) == null) {
// There was no mapping for the key
return true;
} else { if (value.equals(newValue)) {
// The mapping <key, newValue> already exists in the map
return false;
} else {
concurrentHashMap.put(key, newValue);
return true;
}
}
}
}
我读到(在并发包文档中)
并发集合是线程安全的,但不受单个排除锁的控制。
所以你不能在 ConcurrentHashMap 上获得排他锁。
我的问题是:
上面的代码是线程安全的吗?对我来说似乎可以保证同步块中的代码只能由单个线程同时执行,但我想确认一下。
在这种情况下使用 Collections.synchronizedMap() 代替 ConcurrentHashMap 不是更“干净”吗?
非常感谢!
【问题讨论】:
-
真的是'concurrentHashMap.putIfAbsent(msg, msg)'吗?
-
@isnot2bad 不,我更正了,谢谢
-
你能用比较和设置循环代替锁吗? blog.slaks.net/2013-07-22/thread-safe-data-structures
-
@ovdsrn 您在 EDIT 中建议的代码将不起作用,因为 putIfAbsent 如果已经有此键的映射,则不会执行任何操作。
-
@isnot2bad 你说的很对,傻我,我会删除编辑,因为它没有意义。
标签: java multithreading concurrency synchronized java.util.concurrent